package WORKPLACE;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Vector;

import javax.swing.JTable;

import org.dom4j.Element;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonParser;

import ASSET.PROCESS.c_process;
import ORDER.c_order;
import ORDER.m_order;
import ORDER.m_processState;
import TOOLS.SQLtool;
import TOOLS.errCodeManagement;
import TOOLS.messageTool;

public class stationClient {
	messageTool mt=new messageTool();
	public String usrHome = System.getProperty("user.home");
	public String log,iRate;
	public String errMSG="";
	/**
	 * 	工单模式:<BR>
	 * 	true=必须激活,此模式更节约服务器和网络资源<BR>
	 * 	false=自由工单,此模式每次卡前站和上传需要做（后台自动）更多查询<BR>
	 */
	public boolean orderActiveRequired=true;
	public boolean isGetStationInfo=false;
	public String activeOrderNumber="";
//	public String myOrderNumber="";
	public String myProcedureNumber="";
	public m_order sonOrderInfo=null;
	public m_order [] activeOrderInfo=null;
	public m_order [] activeOrderInfo_master=null;
	public m_order [] activeOrderInfo_panel=null;
	public m_order [] activeOrderInfo_part=null;
	public String myStationID,myStationName,myLineID;
	/**
	 * 	面别 <BR>
	 * 	1=T <BR>
	 * 	0=B <BR>
	 */
	public int myLayer;
	/**
	 * int[0]=工步step<BR>
	 * int[1]=必过站feedBack
	 */
	public int [] myProcessStepInfo=null;
	public String lastSN="";
	public long lastState=-1;
	public boolean isPanel=false;
	public boolean checkPanelPermissionState=true;
	public boolean checkPanelFinishState=true;
//	productionCounter iPC=null;
	SQLtool sql=null;
	/**
	 * 	1、连接服务器
	 * 	2、获取设备(站点)信息————工单、本站点所处工步
	 * 	3、设置工单模式orderActiveRequired(默认为必须激活工单模式，此模式更节约资源更高效)
	 * 	3.1、核对资源&激活工单
	 * 	4、开工
	 * 	4.1、卡前站
	 * 	4.2、过站登记	 
	 * @param iSQLpool 
	 */
	public stationClient(SQLtool iSql) throws Exception {
		if(iSql!=null) {
			sql=iSql;
//			iPC=new productionCounter(iSql);
//			iPC.start();
		}
		
		isGetStationInfo=false;
	}
	
	public stationClient copyStation(stationClient oldSC) throws Exception {
		if(oldSC==null) {
			oldSC=this;
		}
		stationClient newSC=new stationClient(oldSC.sql);
		if(oldSC.activeOrderInfo!=null) {
		newSC.activeOrderInfo=oldSC.activeOrderInfo.clone();}
		if(oldSC.activeOrderInfo_master!=null) {
		newSC.activeOrderInfo_master=oldSC.activeOrderInfo_master.clone();}
		if(oldSC.activeOrderInfo_panel!=null) {
		newSC.activeOrderInfo_panel=oldSC.activeOrderInfo_panel.clone();}
		if(oldSC.activeOrderInfo_part!=null) {
		newSC.activeOrderInfo_part=oldSC.activeOrderInfo_part.clone();}
		newSC.activeOrderNumber=oldSC.activeOrderNumber;
		newSC.checkPanelFinishState=oldSC.checkPanelFinishState;
		newSC.checkPanelPermissionState=oldSC.checkPanelPermissionState;
		newSC.isGetStationInfo=oldSC.isGetStationInfo;
		newSC.isPanel=oldSC.isPanel;
		newSC.lastSN=oldSC.lastSN;
		newSC.lastState=oldSC.lastState;
		newSC.myLayer=oldSC.myLayer;
		newSC.sonOrderInfo=oldSC.sonOrderInfo;
		newSC.myProcedureNumber=oldSC.myProcedureNumber;
		if(oldSC.myProcessStepInfo!=null) {
		newSC.myProcessStepInfo=oldSC.myProcessStepInfo.clone();}
		newSC.myLineID=oldSC.myLineID;//myLineID
		newSC.myStationID=oldSC.myStationID;//myLineID
		newSC.myStationName=oldSC.myStationName;
		newSC.orderActiveRequired=oldSC.orderActiveRequired;
		newSC.usrHome=oldSC.usrHome;
//		newSC.iPC.setStationID(oldSC.myStationID);
		return newSC;
	}
	
	/**
	 * 	这种方式复制的工位不连接sql，计数器也不打开
	 * @param oldSC
	 * @return
	 * @throws Exception
	 */
	public stationClient copyStation1(stationClient oldSC) throws Exception {
		if(oldSC==null) {
			oldSC=this;
		}
		stationClient newSC=new stationClient(null);
		if(oldSC.activeOrderInfo!=null) {
		newSC.activeOrderInfo=oldSC.activeOrderInfo.clone();}
		if(oldSC.activeOrderInfo_master!=null) {
		newSC.activeOrderInfo_master=oldSC.activeOrderInfo_master.clone();}
		if(oldSC.activeOrderInfo_panel!=null) {
		newSC.activeOrderInfo_panel=oldSC.activeOrderInfo_panel.clone();}
		if(oldSC.activeOrderInfo_part!=null) {
		newSC.activeOrderInfo_part=oldSC.activeOrderInfo_part.clone();}
		newSC.activeOrderNumber=oldSC.activeOrderNumber;
		newSC.checkPanelFinishState=oldSC.checkPanelFinishState;
		newSC.checkPanelPermissionState=oldSC.checkPanelPermissionState;
		newSC.isGetStationInfo=oldSC.isGetStationInfo;
		newSC.isPanel=oldSC.isPanel;
		newSC.lastSN=oldSC.lastSN;
		newSC.lastState=oldSC.lastState;
		newSC.myLayer=oldSC.myLayer;
		newSC.sonOrderInfo=oldSC.sonOrderInfo;
		newSC.myProcedureNumber=oldSC.myProcedureNumber;
		if(oldSC.myProcessStepInfo!=null) {
		newSC.myProcessStepInfo=oldSC.myProcessStepInfo.clone();}
		newSC.myLineID=oldSC.myLineID;//myLineID
		newSC.myStationID=oldSC.myStationID;//myLineID
		newSC.myStationName=oldSC.myStationName;
		newSC.orderActiveRequired=oldSC.orderActiveRequired;
		newSC.usrHome=oldSC.usrHome;
		
		return newSC;
	}
	
	public void config() throws Exception {
		sql=new SQLtool();
		sql.config("10.130.1.19","AKS2019", "sa", "abcd1234!","stationClient.jar");
		String IPaddr="192.168.1.1";
		try {
			InetAddress addr = InetAddress.getLocalHost();
			IPaddr=addr.getHostAddress();
		} catch (UnknownHostException e1) {
			;
		}
//		sql.config(IPaddr, "AKS2019", "sa", "123456");
		if(IPaddr.startsWith("10.13")) {
			sql.setServer("10.130.1.19");
		}else {
			sql.setServer("192.168.0.39");
		}
		sql.connect();
	}
	
	public void getActiveOrderInfo(String iActiveOrderNumber) throws Exception {
		Thread t1=new Thread(new Runnable() {
			String myActiveOrderNumber=iActiveOrderNumber;
			@Override
			public void run() {
				try {
					activeOrderInfo_master=null;
					activeOrderInfo_master=new c_order(sql).getMasterOrderInfo(myActiveOrderNumber);
					isPanel=false;
				} catch (Exception e1) {
					;
				}
			}
		});
		Thread t2=new Thread(new Runnable() {
			String myActiveOrderNumber=iActiveOrderNumber;
			@Override
			public void run() {
				try {
					activeOrderInfo_panel=null;
					activeOrderInfo_panel=new c_order(sql).getPanelOrderInfo(myActiveOrderNumber);
					isPanel=true;
				} catch (Exception e1) {
					;
				}
			}
		});
		Thread t3=new Thread(new Runnable() {
			String myActiveOrderNumber=iActiveOrderNumber;
			@Override
			public void run() {
				try {
					activeOrderInfo_part=null;
					activeOrderInfo_part=new c_order(sql).getPartOrderInfo(myActiveOrderNumber);
					isPanel=false;
				} catch (Exception e1) {
					;
				}
			}
		});
		t1.start();
		t2.start();
		t3.start();
		t1.join();
		t2.join();
		t3.join();
		
		if(isPanel) {
			activeOrderInfo=activeOrderInfo_panel;
		}else {
			if(activeOrderInfo_part!=null) {
				activeOrderInfo=activeOrderInfo_part;
			}
			if(activeOrderInfo_master!=null) {
				activeOrderInfo=activeOrderInfo_master;
			}
		}
	}
	
	public void getStationSetting(String iStationID) throws Exception {
		String strSql="select orderNumber,procedureNumber,name,"
				+ "isnull(activeLayer,2) as activeLayer,"
				+ "isnull(activeRequire,1) as activeRequire,lineID "
				+ "from dbo.assetStation where ID='"+iStationID+"'";
		JTable t=sql.select(strSql);
		if((t==null)||(t.getRowCount()<1)) {
			throw new Exception("-147");
		}
		myProcedureNumber=(String)t.getValueAt(0, 1);
		if((myProcedureNumber==null)||(myProcedureNumber.length()<1)) {
			throw new Exception("-149");
		}
		String activeRequire=""+t.getValueAt(0, 4);
		if(activeRequire.equals("1")) {
			orderActiveRequired=true;
		}else {
			orderActiveRequired=false;
		}
//		if(myProcedureNumber.equals("A0200")||myProcedureNumber.equals("A0210")) {// 全检和外箱标签可以不激活工单
//			orderActiveRequired=false;
//		}
		myLayer=Integer.parseInt((String)t.getValueAt(0, 3));
		isGetStationInfo=true;
		myStationID=iStationID;
		myLineID=(String)t.getValueAt(0, 5);
		myStationName=(String)t.getValueAt(0, 2);
//		if(orderActiveRequired) {//是不是要求激活工单，都要获取是否拼板，所以屏蔽if(orderActiveRequired)
			activeOrderNumber=(String)t.getValueAt(0, 0);
			if((activeOrderNumber==null)||(activeOrderNumber.length()<1)) {
				throw new Exception("-148");
			}
			// 确认是拼板工单还是总成工单
			getActiveOrderInfo(activeOrderNumber);
			if((activeOrderInfo!=null)&&(activeOrderInfo.length==1)) {//获取工步定位需要到卡前站中补充
				sonOrderInfo=activeOrderInfo[0];
				boolean isOld=false;
				if(sonOrderInfo.orderNumber.equals(sonOrderInfo.masterOrderNumber) && 
						(!sonOrderInfo.orderNumber.startsWith("repair"))) {
					isOld=true;
				}
				try {
					myProcessStepInfo=new c_process(sql).getFlowStep(sonOrderInfo.flowListIndex, myProcedureNumber, myLayer,isOld);
				} catch (Exception e1) {
					if(e1.getMessage().equals("-150")) {
						myProcessStepInfo=null;
					}else {
						throw e1;
					}
				}
			}else {
				sonOrderInfo=null;//激活的是总成工单，还不能确定子板是哪一个
			}
//		}
//		if(this.iPC!=null) {
//			this.iPC.setStationID(iStationID);
//		}
	}
	
	public void getStationSetting(String iStationID,int iLayer) throws Exception {
		myLayer=iLayer;
		getStationSetting(iStationID);
	}
	
	public void freshOrderWipQty(String iOrderNumber) throws Exception {
		String str="select processStateSheet,initState4sn,orderNumber "
				+ "from vOrderListPartPanel where masterOrderNumber='"+iOrderNumber
				+"' or panelOrderNumber ='"+iOrderNumber+"' or orderNumber='"+iOrderNumber+"'";
		JTable t=sql.select(str);
		if(t==null||t.getRowCount()<1) {
			throw new Exception("-162");
		}
		for(int i=0;i<t.getRowCount();i++) {
			String sheetName=(String)t.getValueAt(i, 0);
//			String initState4sn=(String)t.getValueAt(i, 1);
			String iiOrderNumber=(String)t.getValueAt(i, 2);
			str="update order_list set wipQty = A.qty "
					+ "from (select count(1) as qty from [orderWIP].["+sheetName+"] ) A "
					+ "where orderNumber='"+iiOrderNumber+"'";
			sql.Command(str);
		}
	}
	
	public void freshOrderWipQty_II(String iOrderNumber) throws Exception {
		new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					String str="select processStateSheet,initState4sn,orderNumber "
							+ "from vOrderListPartPanel where masterOrderNumber='"+iOrderNumber
							+"' or panelOrderNumber ='"+iOrderNumber+"' or orderNumber='"+iOrderNumber+"'";
					JTable t=sql.select(str);
					if(t==null||t.getRowCount()<1) {
						throw new Exception("-162");
					}
					for(int i=0;i<t.getRowCount();i++) {
						String sheetName=(String)t.getValueAt(i, 0);
			//			String initState4sn=(String)t.getValueAt(i, 1);
						String iiOrderNumber=(String)t.getValueAt(i, 2);
						str="update order_list set wipQty = A.qty "
								+ "from (select count(1) as qty from [orderWIP].["+sheetName+"] ) A "
								+ "where orderNumber='"+iiOrderNumber+"'";
						sql.Command(str);
					}
				}catch(Exception e) {
					;
				}
				
			}
		}).start();
	}
	
	public void freshOrderWipQty_station(String iStation) throws Exception {
		String strSql="select orderNumber,procedureNumber,name from assetStation where ID='"+iStation+"'";
		JTable t=sql.select(strSql);
		if((t==null)||(t.getRowCount()<1)) {
			throw new Exception("-147");
		}
		String iOrderNumber=(String)t.getValueAt(0, 0);
		freshOrderWipQty(iOrderNumber);
	}
	
	/**
	 * 	切换工位当前工单
	 * @param iOrderNumber
	 * @throws Exception
	 */
	public void changeStationOrder(String iOrderNumber,int iLayer) throws Exception {
		if(!isGetStationInfo) {
			throw new Exception("-151");
		}
		myLayer=iLayer;
		getActiveOrderInfo(iOrderNumber);

//		if(activeOrderInfo!=null) { //240409 杨部长以后备料状态不用卡了
//			if(isPanel) {
//				for(int i=0;i<activeOrderInfo.length;i++) {
//					if(activeOrderInfo[i].isPrepared==1) {
//						throw new Exception("-183");
//					}
//				}
//			}
//		}
		
		activeOrderNumber=iOrderNumber;
		sql.Command("update assetStation set orderNumber='"+iOrderNumber+"',activeLayer="+myLayer
				+" where ID='"+myStationID+"'");
		if((activeOrderInfo!=null)&&(activeOrderInfo.length==1)) {//获取工步定位需要到卡前站中补充
			sonOrderInfo=activeOrderInfo[0];
			boolean isOld=false;
			if(sonOrderInfo.orderNumber.equals(sonOrderInfo.masterOrderNumber)&& 
					(!sonOrderInfo.orderNumber.startsWith("repair"))) {
				isOld=true;
			}
			myProcessStepInfo=new c_process(sql).getFlowStep(sonOrderInfo.flowListIndex, myProcedureNumber, myLayer,isOld);
		}else {
			sonOrderInfo=null;//总成工单中有多个子板工单，不能确定是哪一个
		}
	}

	/**
	 * 	切换工位当前工单
	 * @param iOrderNumber
	 * @throws Exception
	 */
	public void changeStationOrder(String iOrderNumber) throws Exception {
		changeStationOrder(iOrderNumber,myLayer);
	}
	
	/**
	 * 	切换工位当前工单	<BR>
	 * 	iType=0 --> iKey=iOrderNumber	<BR>
	 * 	iType=1 --> iKey=iModelNo (即产品编号版本号BIN号共18位)	<BR>
	 * @throws Exception
	 */
	public void changeStationOrder(String iKey,int iLayer,int iType) throws Exception {
		if(!isGetStationInfo) {
			throw new Exception("-151");
		}
		if(iType==0) {
			myLayer=iLayer;
			activeOrderNumber=iKey;
		}else if(iType==1){// 到韩赢的排产表中查询当天的iModelNo对应的工单
			String partNumber=iKey.substring(0, 12);
			String version=iKey.substring(13, 15);
			String BIN=iKey.substring(15, 18);
			activeOrderNumber=webAPI_getOrderNo(partNumber,version,BIN);
			if((activeOrderNumber==null)||(activeOrderNumber.length()<1)) {
				throw new Exception("-162");
			}
		}
		new Thread(new Runnable() {
			@Override
			public void run() {
				try {//刷新新同步物料料盘的MSD剩余时间 
					String sqlStr="update mID set mID.MSD_lastAge=lmt.MSDvalidity \r\n" + 
							"from materialID mID \r\n" + 
							"LEFT JOIN logistics_materalType lmt ON mID.partNumber=lmt.partNumber \r\n" + 
							"where mID.MSD_lastAge=-1 and lmt.MSDlevel in (select MSDLevel from MSDlevel) ";
					sql.Command(sqlStr);
				} catch (Exception e1) {
					;
				}
			}
		}).start();
		getActiveOrderInfo(activeOrderNumber);

//		if(activeOrderInfo!=null) {	//240409 杨部长:以后备料状态不用卡了
//			if(isPanel) {
//				for(int i=0;i<activeOrderInfo.length;i++) {
//					if(activeOrderInfo[i].isPrepared==1) {
//						throw new Exception("-183");//工单未完成备料
//					}
//				}
//			}
//		}
		
		if((activeOrderInfo!=null)&&(activeOrderInfo.length==1)) {// 获取工步定位需要到卡前站中补充
			sonOrderInfo=activeOrderInfo[0];
			boolean isOld=false;
			if(sonOrderInfo.orderNumber.equals(sonOrderInfo.masterOrderNumber)&& 
					(!sonOrderInfo.orderNumber.startsWith("repair"))) {
				isOld=true;
			}
			myProcessStepInfo=new c_process(sql).getFlowStep(sonOrderInfo.flowListIndex, myProcedureNumber, myLayer,isOld);
		}else {
			if(activeOrderInfo==null) {
				throw new Exception("-146@工单号:"+activeOrderNumber+"_不存在");// 工单不存在
			}
			sonOrderInfo=null;//总成工单中有多个子板工单，不能确定是哪一个
		}
		sql.Command("update [dbo].[assetStation] set orderNumber='"+activeOrderNumber+"',activeTime=GETDATE(),activeLayer="
				+myLayer+",okQuantity=0,ngQuantity=0 where ID='"+myStationID
				+"' and (orderNumber!='"+activeOrderNumber+"' or orderNumber is null "
						+ "or activeLayer!="+myLayer+" or activeLayer is null )");//20230413 切换不同工单增加quantity归零
		//20230418 工单和面别是null时，也要切换
		if(myStationID.equals("S01-L12-DEPANEL-M1")) {
			sql.Command("update [dbo].[assetStation] set activeTime=GETDATE(),okQuantity=0,ngQuantity=0 where (ID='S01-L12-DEPANEL-M1' or ID='S01-L72-FCT-M1') ");
		}//230719 由于自动线FCT需要多工单同时过站，由同线的铣板带动更新计数器
		
	}
	
	public static String webAPI_getOrderNo(String partNumber,String version,String BIN) {
		String IPaddr="192.168.1.1";
		try {
			InetAddress addr = InetAddress.getLocalHost();
			IPaddr=addr.getHostAddress();
		} catch (UnknownHostException e1) {
			;
		}
		URLapi aa=new URLapi();
		if(IPaddr.startsWith("10.130")) {
			aa.RESTInvoker("http://10.130.0.231:8080", "","");
		}else {
			aa.RESTInvoker("http://192.168.0.240:8080", "","");
		}
		String str1="";
		String str=aa.getDataFromServer("/actionapi/Ordermanager/Getorderbypart?part_no="+partNumber+"-"+version+"&bin="+BIN);
//		System.out.println(str);
		str1 =str.replaceAll("\\\\", "");
		str1=str1.substring(1,(str1.length()-1));
//		System.out.println(str1);
		Gson gson=new Gson();
		JsonParser parser = new JsonParser();
		JsonArray Jarray = parser.parse(str1).getAsJsonArray();
		int mRow=Jarray.size();
		m_orderNo [] mTable=new m_orderNo[mRow];
		if(mRow>0) {
			for(int i=0;i<mRow;i++) {
				mTable[i]=new m_orderNo();
				String iCounter=Jarray.get(i).toString();
				mTable[i]=gson.fromJson(iCounter, m_orderNo.class);
			}
//			System.out.println(mTable[0].order_no);
			return mTable[0].order_no;
		}else {
			return null;
		}
	}
	
	public m_SNinfo getSNinfo(String iSN) throws Exception {
		m_SNinfo result=null;
		String strSql="SELECT serialNumber,state,orderNumber,partNumber,partName,BSindex,panelSN,pos,panelOrderNumber,"
				+ "comp,compName,desc1,desc2,desc3,desc4 " + 
				"FROM vSerialNumberBINdesc " + 
				"where serialNumber='"+iSN+"' order by comp";
		try {
			JTable t=sql.select(strSql);
			if(t==null||t.getRowCount()<1) {
				throw new Exception("-152");
			}
			result=new m_SNinfo();
			result.wipno=(String)t.getValueAt(0, 0);
			result.state=Integer.parseInt((String)t.getValueAt(0, 1));
			result.lotNo=(String)t.getValueAt(0, 2);
			result.createTime=sql.selectFirstValue("select createTime from vOrderList where orderNumber ='"
					+result.lotNo+"'");
			result.number=(String)t.getValueAt(0, 3);
			result.name=(String)t.getValueAt(0, 4);
			result.bin=(String)t.getValueAt(0, 5);
			result.panelWipno=(String)t.getValueAt(0, 6);
			try {
				result.position=Integer.parseInt((String)t.getValueAt(0, 7));
			}catch(Exception ex) {
				result.position=-1;
			}
			result.panelLotNo=(String)t.getValueAt(0, 8);
			result.BINcomps=(String)t.getValueAt(0, 9);
			result.led1=(String)t.getValueAt(0, 11);
			if(result.led1==null) {
				result.led1="";
			}
			result.led2=(String)t.getValueAt(0, 12);
			if(result.led2==null) {
				result.led2="";
			}
			result.led3=(String)t.getValueAt(0, 13);
			if(result.led3==null) {
				result.led3="";
			}
			result.led4=(String)t.getValueAt(0, 14);
			if(result.led4==null) {
				result.led4="";
			}
			for(int i=1;i<t.getRowCount();i++) {
				String iBINcomps=(String)t.getValueAt(i, 9);
				if(iBINcomps.length()>0) {
					if(result.BINcomps.length()>0) {
						result.BINcomps=result.BINcomps+",";
					}
					result.BINcomps=result.BINcomps+iBINcomps;
				}
				String iled1=(String)t.getValueAt(i, 11);
				if(iled1.length()>0) {
					if(result.led1.length()>0) {
						result.led1=result.led1+",";
					}
					result.led1=result.led1+iled1;
				}
				String iled2=(String)t.getValueAt(i, 12);
				if(iled2.length()>0) {
					if(result.led2.length()>0) {
						result.led2=result.led2+",";
					}
					result.led2=result.led2+iled2;
				}
				String iled3=(String)t.getValueAt(i, 13);
				if(iled3.length()>0) {
					if(result.led3.length()>0) {
						result.led3=result.led3+",";
					}
					result.led3=result.led3+iled3;
				}
				String iled4=(String)t.getValueAt(i, 14);
				if(iled4.length()>0) {
					if(result.led4.length()>0) {
						result.led4=result.led4+",";
					}
					result.led4=result.led4+iled4;
				}
			}
			return result;
		} catch (Exception e) {
			throw new Exception("条码"+iSN+"信息查询失败");
		}
	}
	
	public String webAPI_getSNinfo(String SN) throws Exception {
		String startT=GetTimestamp();
		String IPaddr="192.168.1.1";
		try {
			InetAddress addr = InetAddress.getLocalHost();
			IPaddr=addr.getHostAddress();
		} catch (UnknownHostException e1) {
			;
		}
		URLapi aa=new URLapi();
//		IPaddr="10.130.1.1";
//		System.out.println(IPaddr);
		if(IPaddr.startsWith("10.130")) {
//			aa.RESTInvoker("http://10.130.0.231:8080", "","");
			aa.RESTInvoker("http://10.130.0.231:8092", "","");
		}else {
//			aa.RESTInvoker("http://192.168.0.240:8080", "","");
			aa.RESTInvoker("http://192.168.0.240:8092", "","");
		}
		String str1="",str="",APIerrText="";
		str=aa.getDataFromServer("/actionapi/Wip/Getproduct?wipno="+SN);
		String webAPIT=GetTimestamp();
		long diffMS=getDiffMS(startT,webAPIT);
		if(diffMS>2000) {
			APIerrText=str;
			String Tlog="webAPIt="+diffMS+"ms,APItext="+APIerrText;
			new Thread(new Runnable() {
				@Override
				public void run() {
					try {
						AKSLogs(-107,Tlog);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}).start();
		}
//		System.out.println(str);
		str1 =str.replaceAll("\\\\", "");
		str1=str1.substring(1,(str1.length()-1));
		Gson gson=new Gson();
		JsonParser parser = new JsonParser();
		JsonArray Jarray=null;
		try {
			Jarray= parser.parse(str1).getAsJsonArray();
		}catch(Exception e) {
			str1="["+str1+"]";
			Jarray= parser.parse(str1).getAsJsonArray();
		}
//		System.out.println(str1);
		int mRow=Jarray.size();
		m_SNinfo [] mTable=new m_SNinfo[mRow];
		if(mRow>0) {
			for(int i=0;i<mRow;i++) {
				mTable[i]=new m_SNinfo();
				String iCounter=Jarray.get(i).toString();
				mTable[i]=gson.fromJson(iCounter, m_SNinfo.class);
			}
			if(mTable[0].number.startsWith("5.")) {// 如果是5.00起头的部件，按照总成结构查询总成1.00.01.0000-00，转换
				String model=mTable[0].number.substring(0, 12);
				String ver=mTable[0].number.substring(12, 15);
				String strSQl="select masterNumber from product_struct where partNumber = '"+model+"'";
				try {
					JTable it=sql.select(strSQl);
					if(it.getRowCount()>0) {
						strSQl=(String) it.getValueAt(0, 0);
						mTable[0].number=strSQl+ver;
					}
				} catch (Exception e) {
					;
				}
			}
//			System.out.println(mTable[0].order_no);
			return mTable[0].number+mTable[0].bin;
		}else {
			return null;
		}
	}

	public boolean checkWIPpermmision(String iSerialNumber) throws Exception {
		return checkWIPpermmision(iSerialNumber,"-1","-1");
	}
	
	/**
	 * 	卡前站
	 * @param iSerialNumber
	 * @return	true=允许开工，false=禁止开工
	 * @throws Exception
	 */
	public boolean checkWIPpermmision(String iSerialNumber,String iisPanel,String procedure) throws Exception {
		boolean isOld=true;
		if(procedure.equals("-1")) {
			procedure=myProcedureNumber;
		}
		if(!isGetStationInfo) {
			throw new Exception("-151");
		}
		if(iisPanel.equals("1")) {
			return checkPanelWIPpermmision(iSerialNumber,procedure);
		}else if(iisPanel.equals("0")){
			;
		}else {
			if(isPanel) {
				return checkPanelWIPpermmision(iSerialNumber,procedure);
			}
		}
		String iState,XRayFlag,dateFlag="default";
		int nOrderIndex=-1;
		String panelOrder="";
		// 判断是否样件
		boolean isSamplePCB=checkSamplePCB(iSerialNumber,procedure);
		if(isSamplePCB) {
			return true;
		}
		String strsQL="select sn,tips from QM.quarantinedList where sn='"+iSerialNumber+"'";
		JTable t=sql.select(strsQL);
		if(t!=null && t.getRowCount()>0) {
			String errTips="产品隔离！"+t.getValueAt(0, 1);
			throw new Exception(errTips);
		}
		strsQL="select orderIndex,state,XRayFlag,createTime,panelOrderNumber from order_serialNumber where serialNumber='"+iSerialNumber+"'";
		t=sql.select(strsQL);
		if(t.getRowCount()>0) {
			nOrderIndex=Integer.parseInt((String)t.getValueAt(0, 0));
			iState=(String)t.getValueAt(0, 1);
			XRayFlag=(String)t.getValueAt(0, 2);
			dateFlag=(String)t.getValueAt(0, 3);
			panelOrder=(String)t.getValueAt(0, 4);
			dateFlag=dateFlag.substring(0, 7);
			dateFlag=dateFlag.replaceAll("-", "");
			dateFlag=dateFlag.replaceAll(":", "");
			dateFlag=dateFlag.replaceAll(" ", "");
			if(iState.equals("0")||iState.equals("3")) {
				throw new Exception("-163");	// 品质模块需要判定投入
			}
			if(XRayFlag.equals("1")) {
				throw new Exception("-173");	// XRay标记没消除，待照XRay
			}
			if(procedure.equals("A0060")) {// AOI检查XRAYflag
				if(XRayFlag.equals("2")) {
					throw new Exception("-173");	// XRay标记没消除，待照XRay
				}
			}
		}else {
			throw new Exception("-152");
		}
		m_order snOrderInfo=c_order.getOrderInfo_cut(sql,nOrderIndex);
		if(!orderActiveRequired){//无需先激活工单的模式
			sonOrderInfo=snOrderInfo;
			isOld=false;
			if(sonOrderInfo.orderNumber.equals(sonOrderInfo.masterOrderNumber)&& 
					(!sonOrderInfo.orderNumber.startsWith("repair"))) {
				isOld=true;
			}
			myProcessStepInfo=new c_process(sql).getFlowStep(sonOrderInfo.flowListIndex, procedure, myLayer,isOld);
		}else {//在masterOrder中寻找nOrderNumber是否属于sonOrder,把正确的sonOrder赋值给myOrderInfo，如果不属于则throw new Exception("-153");
			boolean checked=false;
			if(sonOrderInfo!=null) {
				if(isPanel) {
					if(panelOrder.equals(sonOrderInfo.panelOrderNumber)) {
						checked=true;
					}
				}else {
					if(nOrderIndex!=sonOrderInfo.orderIndex) {
						checked=false;
					}else {
						isOld=false;
						if(sonOrderInfo.orderNumber.equals(sonOrderInfo.masterOrderNumber)&& 
								(!sonOrderInfo.orderNumber.startsWith("repair"))) {
							isOld=true;
						}
						checked=true;
					}
				}
			}else {
//				throw new Exception("-148");//工位当前无激活工单 //*不能认定无工单，有可能是激活的总成工单还不能确定子板
			}
			if(checked==false) {
				if(activeOrderInfo==null) {
					throw new Exception("-148");
				}
				if(isPanel) {
					if(panelOrder.equals(activeOrderInfo[0].panelOrderNumber)) {//240319新增，应对拼板工单单板过站的返工单过站
						checked=true;
						isOld=false;
						myProcessStepInfo=new c_process(sql).getFlowStep(snOrderInfo.flowListIndex, procedure, myLayer,isOld);
					}
				}else {
					for(int i=0;i<activeOrderInfo.length;i++) {
						if(nOrderIndex==activeOrderInfo[i].orderIndex) {
							checked=true;
							isOld=false;
//							sonOrderInfo=snOrderInfo;//*不能认定子板工单，有可能故意激活总成工单来做各个子板一起进站
							if(snOrderInfo.orderNumber.equals(snOrderInfo.masterOrderNumber)&& 
									(!snOrderInfo.orderNumber.startsWith("repair"))) {
								isOld=true;
							}
							myProcessStepInfo=new c_process(sql).getFlowStep(snOrderInfo.flowListIndex, procedure, myLayer,isOld);
							i=activeOrderInfo.length;
						}
					}
				}
				
				if(checked==false) {
					throw new Exception("-153@"+iSerialNumber+"工单="+snOrderInfo.orderNumber);
				}
			}
		}
		String strSql="select processState from [orderWIP].["+snOrderInfo.processStateSheet+"] where serialNumber='"+iSerialNumber+"'";
		t=sql.select(strSql);
		if((t==null)||(t.getRowCount()<1)) {
			if(nOrderIndex==snOrderInfo.orderIndex) {
				sql.Command("insert [orderWIP].["+snOrderInfo.processStateSheet+"] (serialNumber,processState) "
						+ "values ('"+iSerialNumber+"',"+snOrderInfo.initState4sn+")");
				t=sql.select(strSql);
			}else {//这个else逻辑上永不发生
				throw new Exception("-153@"+iSerialNumber+"工单="+snOrderInfo.orderNumber);
			}
		}
		m_processState mpS=new m_processState();
		mpS.state=Long.parseLong((String)t.getValueAt(0, 0));
		lastSN=iSerialNumber;
		lastState=mpS.state;
		boolean result=mpS.checkState(myProcessStepInfo[0]);
		if(result) {
			if(procedure.equals("A0200") || procedure.equals("A0202")) {
				strSql="select AAA from FVIfeedBackList where AAA ='"+iSerialNumber+"'";
				t=sql.select(strSql);
				if(t!=null && t.getRowCount()>0) {
					throw new Exception("这一片产品暂时保留，请通知付艳 6716");
				}
			}
			if(procedure.equals("A0100")) {
				strSql="select BBB from FVIfeedBackList where BBB ='"+iSerialNumber+"'";
				t=sql.select(strSql);
				if(t!=null && t.getRowCount()>0) {
					throw new Exception("这一片产品暂时保留，请通知付艳 6716");
				}
			}
		}
		if(myProcessStepInfo[2]>0) {//卡控前站完成时间有效期
			if(result) {
				String sheetN="vProcessFlow_II";
				if(isOld) {
					sheetN="vProcessFlow";
				}
				try {
					strSql="select createTime,DATEDIFF(SECOND, createTime, Getdate()) as diffDate "
							+ "from [SNhistory].[history_uploadState_"+dateFlag+"] \r\n" + 
							"where serialNumber='"+iSerialNumber+"' \r\n" + 
							"and procedureNumber in (select number from "+sheetN
							+" where flowListIndex="+snOrderInfo.flowListIndex
							+" and flowStep="+(myProcessStepInfo[0]-1)+") \r\n" + 
							"ORDER BY createTime desc";
					t=sql.select(strSql);
				}catch(Exception ee) {
					strSql="select createTime,DATEDIFF(SECOND, createTime, Getdate()) as diffDate "
							+ "from [dbo].[history_uploadState] \r\n" + 
							"where serialNumber='"+iSerialNumber+"' \r\n" + 
							"and procedureNumber in (select number from "+sheetN
							+" where flowListIndex="+snOrderInfo.flowListIndex
							+" and flowStep="+(myProcessStepInfo[0]-1)+") \r\n" + 
							"ORDER BY createTime desc";
					t=sql.select(strSql);
				}
				result=false;
				if(t!=null && t.getRowCount()>0) {
					String iDiff=(String)t.getValueAt(0, 1);
					if(iDiff!=null) {
						int diff=Integer.parseInt(iDiff);
						if(diff<myProcessStepInfo[2]) {
							result=true;
						}else {
							throw new Exception("-172");
						}
					}
				}
			}
		}
		return result;
	}
	
	/**
	 * 检查是否样件sn
	 * @param iSerialNumber
	 * @param procedure
	 * @return
	 * @throws Exception 
	 */
	public boolean checkSamplePCB(String iSerialNumber, String procedure) throws Exception {
		boolean result=false;
		iSerialNumber=iSerialNumber.trim();
		String urlstr="";
		String str="select procedureIndex from dbo.processFlow_procedure where number='"+procedure+"'";
		JTable t=sql.select(str);
		if(t!=null && t.getRowCount()>0) {
			String procedureIndex=""+t.getValueAt(0, 0);
			// 调用API接口
			String IPaddr="192.168.1.1";
			try {
				InetAddress addr = InetAddress.getLocalHost();
				IPaddr=addr.getHostAddress();
			} catch (UnknownHostException e1) {
				;
			}
			URLapi aa=new URLapi();
			if(IPaddr.startsWith("10.130")) {
				aa.RESTInvoker("http://10.130.1.13:8081", "","");
			}else {
				aa.RESTInvoker("http://192.168.0.220:8081", "","");
			}//http://10.130.5.23:9004/
//			aa.RESTInvoker("http://10.130.5.23:9004", "","");
//			urlstr="/sample/procedure?sn="+iSerialNumber
//					+"&procedureIndex="+procedureIndex;
			urlstr="/api/extra/sample/procedure?sn="+iSerialNumber.replaceAll(" ", "%20")
					+"&procedureIndex="+procedureIndex;
			str=aa.getDataFromServer(urlstr);
			if(str.equals("true")) {
				result=true;
			}
		}
//		System.out.println("样件结果="+result+"_:"+urlstr);
		return result;
	}

	/**
	 * 	卡前站
	 * @param iSerialNumber
	 * @return	true=允许开工，false=禁止开工
	 * @throws Exception
	 */
	public boolean checkPanelWIPpermmision(String iSerialNumber,String procedure) throws Exception {
		if(!isGetStationInfo) {
			throw new Exception("-151");
		}
		if(procedure.equals("-1")) {
			procedure=myProcedureNumber;
		}
		if(!isPanel) {
			throw new Exception("请先激活拼板工单才能按拼板过站!");
		}else {
			boolean isSamplePCB=checkSamplePCB(iSerialNumber,procedure);
			if(isSamplePCB) {
				return true;
			}
			String iiSerialNumber=iSerialNumber;
			/**
			 * 1.获取设备工序，myProcedureNumber, myLayer已从getStationInfo中获取了,可以直接使用
			 * 2.确定本工序在工艺流程中的工步是否可以进站
			 * 2.1、预检品质不良
			 * 2.2、预检是否本工单产品
			 * 2.3、预检本工序是否可以开工
			 */
			String SQLstr="select orderNumber,serialNumber,flowListIndex,processStateSheet,pos,state,"
					+ "panelOrderNumber,initState4sn,XRayFlag from vOrderSerialNumber "
					+ "where panelSN='"+iiSerialNumber+"' order by pos";
			JTable t=sql.select(SQLstr);
			if((t==null)||(t.getRowCount()<1)) {
				String odsql="select panelSN from vOrderSerialNumber where serialNumber='"+iiSerialNumber+"'";
				JTable ttt=sql.select(odsql);
				if((ttt!=null)&&(ttt.getRowCount()>0)) {
					iiSerialNumber=(String)ttt.getValueAt(0, 0);
					SQLstr="select orderNumber,serialNumber,flowListIndex,processStateSheet,pos,state,"
							+ "panelOrderNumber,initState4sn,XRayFlag from vOrderSerialNumber "
							+ "where panelSN='"+iiSerialNumber+"' order by pos";
					t=sql.select(SQLstr);
				}
			}
			if((t!=null)&&(t.getRowCount()>0)) {
				checkPanelPermissionState=true;
				boolean iResult[]=new boolean[t.getRowCount()];
				String errTest[]=new String[t.getRowCount()];
				Thread [] iT=new Thread[t.getRowCount()];
				for(int i=0;i<t.getRowCount();i++) {
					if(checkPanelPermissionState) {
						String gSerialNumber=(String)t.getValueAt(i, 1);
						int gFlowListIndex=Integer.parseInt((String)t.getValueAt(i, 2));
						String gProcessStateSheet=(String)t.getValueAt(i, 3);
						int gState=Integer.parseInt((String)t.getValueAt(i, 5));
						String gPanelOrder=(String)t.getValueAt(i, 6);
						String gInitState4sn=(String)t.getValueAt(i, 7);
						int gXRayFlag=Integer.parseInt((String)t.getValueAt(i, 8));
						if(orderActiveRequired) {//核对是否符合工单要求
							if(!gPanelOrder.equals(activeOrderNumber)) {
								throw new Exception("-153@"+iSerialNumber+"工单="+gPanelOrder);
							}
						}
						if(gState==0) {
							throw new Exception("-163");	// 品质模块需要判定投入
						}
						if(gXRayFlag==1) {
							throw new Exception("-173");	// XRay标记没消除，待照XRay
						}
						if(procedure.equals("A0060")) {// AOI检查XRAYflag
							if(gXRayFlag==2) {
								throw new Exception("-173");	// XRay标记没消除，待照XRay
							}
						}
						int iIndex=i;
						String iprocedure=procedure;
						iT[i]=new Thread(new Runnable() {//子板预检
							String iiSerialNumber=gSerialNumber;
							int iiFlowListIndex=gFlowListIndex;
							String iiProcessStateSheet=gProcessStateSheet;
							int iiNdex=iIndex;
							String iInitState4sn=gInitState4sn;
							int iiState=gState;
							String iiprocedure=iprocedure;
							@Override
							public void run() {
								if(checkPanelPermissionState) {
									try {
										if(iiState==3) {//人工报废的，前道都允许501通过
											iResult[iiNdex]=true;
										}else {
											int [] iProcessStepInfo=new c_process(sql).getFlowStep(iiFlowListIndex, iiprocedure, myLayer,false);
											m_processState mpS=new m_processState();
											mpS.state=0;
											String strSql="select processState from [orderWIP].["+iiProcessStateSheet+"] where serialNumber='"+iiSerialNumber+"'";
											JTable tt=sql.select(strSql);
											if((tt==null)||(tt.getRowCount()<1)) {
												sql.Command("insert [orderWIP].["+iiProcessStateSheet+"] (serialNumber,processState) "
														+ "values ('"+iiSerialNumber+"',"+iInitState4sn+")");
												tt=sql.select(strSql);
											}
											mpS.state=Long.parseLong((String)tt.getValueAt(0, 0));
											iResult[iiNdex]=mpS.checkState(iProcessStepInfo[0]);
											if(checkPanelPermissionState) {
												checkPanelPermissionState=iResult[iiNdex];
											}
											if(!iResult[iiNdex]) {
												errTest[iiNdex]="子板"+iiSerialNumber+"前站异常";
											}
										}
										
									} catch (Exception e1) {
										try {
											errTest[iiNdex]=errCodeManagement.getErrText(e1.getMessage());
											AKSLogs(-31,"拼板"+iiSerialNumber+"预检失败!"+e1.getMessage());
										} catch (Exception e) {
											e.printStackTrace();
										}
									}
								}
							}
						});
						iT[i].start();//子板过站
					}
				}
				if(checkPanelPermissionState) {
					for(int i=0;i<t.getRowCount();i++) {
						if(checkPanelPermissionState) {
							iT[i].join();
							if(!iResult[i]) {
								throw new Exception(errTest[i]);
							}
						}else {
							return false;
						}
					}
					return true;
				}else {
					return false;
				}
				
			}else {
				throw new Exception("拼板"+iiSerialNumber+"查vOrderSerialNumber子码信息失败");
			}
		}
	}
	

	public void uploadState(String iSerialNumber,boolean iState,String procedure) throws Exception {
		uploadState(iSerialNumber,iState,false,false,procedure);
	}
	public void uploadState(String iSerialNumber,boolean iState) throws Exception {
		uploadState(iSerialNumber,iState,false,false,"-1");
	}
	
//	public void passBy(boolean iState) throws Exception {
//		iPC.setStationID(myStationID);
//		iPC.callCounter(iState);//不启用start的时候不用call
//		
//	}
	public void passBy(boolean iState) throws Exception {// 20230517
		if(iState) {
			sql.Command("update [dbo].[assetStation] set okQuantity=okQuantity+1 where ID='"
					+myStationID+"' ");
		}else {
			sql.Command("update [dbo].[assetStation] set ngQuantity=ngQuantity+1 where ID='"
					+myStationID+"' ");
		}
	}
	
	/**
	 * 	过站登记
	 * @param iSerialNumber
	 * @param iState :<BR>
	 * 	true=Pass<BR>
	 * 	false=Fail
	 * @param executorService 
	 * @throws Exception
	 */
	public void uploadState(String iSerialNumber,boolean iState,boolean iRepair,boolean callXRay,String procedure) throws Exception {
		if(!isGetStationInfo) {
			throw new Exception("-151");
		}
		if(procedure.equals("-1")) {
			procedure=this.myProcedureNumber;
		}
		try {
//			String debugStr="";
			String dateFlag="default";
			if(isPanel) {
				uploadPanelState(iSerialNumber,iState,iRepair,callXRay,procedure);
			}else {
				passBy(iState);// 登记站点过站数量+1
				
				/**
				 * 	String[0]=orderIndex
				 * 	String[1]=repeatCounter
				 * 	String[2]=createTime
				 */
				String [] iSNinfo=null;//待获取SN产品信息
				
				if(iSerialNumber.startsWith("NoSN")) {
					iSNinfo=new String[3];
					if(this.orderActiveRequired) {
						iSNinfo[0]=""+this.activeOrderInfo[0].orderIndex;
						iSNinfo[2]=""+this.activeOrderInfo[0].createTime;
					}else {// 对于不需要激活工单的工位，若不扫码，怎么记？
						return;//暂定不作后续记录
					}
					iSNinfo[1]="0";
				}else {
					try {
						iSNinfo=new c_order(sql).getOrderindexNrepeatCounter(iSerialNumber);//查看是否强制要求重测（次数）
						if(iSNinfo==null) {
							throw new Exception("iSNinfo=null");
						}
					}catch(Exception e) {
						if(e.getMessage().equals("-152")) {
							String realSN=getSN4Label(iSerialNumber);//如果条码未识别，先查询看看是否为标签
							if(realSN!=null) {
								iSerialNumber=realSN;
								iSNinfo=new c_order(sql).getOrderindexNrepeatCounter(iSerialNumber);
							}else {
								throw e;
							}
						}else {
							throw e;
						}
					}
				}
				
				
				
				if(iState&&(procedure.equals("A0180"))) {
					int iSNinfo1=Integer.parseInt(iSNinfo[1]);
					if(iSNinfo1>0) {
						String strss="update order_serialNumber set repeatCounter="+(iSNinfo1-1)
								+" where serialNumber='"+iSerialNumber+"'";
						sql.Command(strss);
						if(iSNinfo1>1) {
							throw new Exception("维修间返回产线，还需重测"+(iSNinfo1-1)+"次PASS才能流通");
						}
					}
				}
				
				dateFlag=iSNinfo[2].substring(0, 7);
				dateFlag=dateFlag.replaceAll("-", "");
				dateFlag=dateFlag.replaceAll(":", "");
				dateFlag=dateFlag.replaceAll(" ", "");

				boolean isOld=false;
				m_order snOrderInfo=new c_order(sql).getOrderInfo_cut(Integer.parseInt(iSNinfo[0]));
				if(!orderActiveRequired){//无需先激活工单的模式
					sonOrderInfo=snOrderInfo;
					if(sonOrderInfo.orderNumber.equals(sonOrderInfo.masterOrderNumber)&& 
							(!sonOrderInfo.orderNumber.startsWith("repair"))) {
						isOld=true;
					}
					myProcessStepInfo=new c_process(sql).getFlowStep(sonOrderInfo.flowListIndex, procedure, myLayer,isOld);
				}else {
					boolean checked=false;
					if(sonOrderInfo==null) {
						for(int i=0;i<activeOrderInfo.length;i++) {
							if(snOrderInfo.orderIndex==activeOrderInfo[i].orderIndex) {
								checked=true;
//								sonOrderInfo=activeOrderInfo[i];//*不能认定子板工单，有可能故意激活总成工单来完成多子板同时进站
								if(snOrderInfo.orderNumber.equals(snOrderInfo.masterOrderNumber)&& 
										(!snOrderInfo.orderNumber.startsWith("repair"))) {
									isOld=true;
								}
								myProcessStepInfo=new c_process(sql).getFlowStep(snOrderInfo.flowListIndex, procedure, myLayer,isOld);
								i=activeOrderInfo.length;
							}
						}
						if(checked==false) {
							throw new Exception("-153@与工位工单不匹配"+iSerialNumber+"工单="+snOrderInfo.orderNumber);
						}
					}
				}
				m_processState mpS=new m_processState();
				String iiiiSerialNumber=iSerialNumber;
				if(!iSerialNumber.startsWith("NoSN")) {
					mpS.state=0;
//					if(iSerialNumber.equals(lastSN)) {
//						mpS.state=lastState;
//					}else //会导致不同子项服务拿到上一次state，不一定是最新的 230721
					if(true){ 
						String strSql="select processState from [orderWIP].["+snOrderInfo.processStateSheet+"] where serialNumber='"+iSerialNumber+"'";
						JTable t=sql.select(strSql);
						if((t==null)||(t.getRowCount()<1)) {
							String nOrderNumber=new c_order(sql).getOrderNumber(iSerialNumber);
							if(nOrderNumber.equals(snOrderInfo.orderNumber)) {
								sql.Command("insert [orderWIP].["+snOrderInfo.processStateSheet+"] (serialNumber,processState) "
										+ "values ('"+iSerialNumber+"',"+snOrderInfo.initState4sn+")");
								t=sql.select(strSql);
							}else {//逻辑上不可能发生
								throw new Exception("-153"+iSerialNumber+"工单="+snOrderInfo.orderNumber);
							}
						}
						mpS.state=Long.parseLong((String)t.getValueAt(0, 0));
//						debugStr=""+mpS.state+"_"+Long.toBinaryString(mpS.state);
					}
					
					
					mpS.setState(myProcessStepInfo[0], iState);
//					debugStr=debugStr+";"+mpS.state+"_"+Long.toBinaryString(mpS.state);
					boolean iiState=iState;
					boolean iisOld=isOld;
					String iprocedure=procedure;
					new Thread(new Runnable() {
						long iState=mpS.state;
						m_processState impS=mpS;
						boolean iResult=iiState;
						boolean iiisOld=iisOld;
						String iiprocedure=iprocedure;
						String iProcessStateSheet=snOrderInfo.processStateSheet;
						@Override
						public void run() {
							try {
								if(!iResult) {//品质状态修改为不良
									if(iiprocedure.equals("A0200") || iiprocedure.equals("A0202")) {// A0200的FAIL强制回A0180 从FCT开始但是不变更打标签状态
										try {
//											int [] FCTstep=new c_process(sql).getFlowStep_last(myOrderInfo.flowListIndex, "A0180",iiisOld);
//											long fnState=(long) (iinitState-
//														(iinitState%Math.pow(2, FCTstep[0]))+
//														(iState%Math.pow(2, FCTstep[0]-1)));
											JTable t=new c_process(sql).getFlow(snOrderInfo.flowListIndex, iiisOld);
											long fnState=iState;
											String iProcessNumber="",iFeedBack="";
											int ihead=0;
											if(t!=null && t.getRowCount()>0) {
												int len=t.getRowCount();
												int ss=0;
												for(int s=len-1;s>=0;s--) {
													iProcessNumber=""+t.getValueAt(s, 2);
													if(iProcessNumber.equals("A0180")) {//从FCT开始
														ihead=1;
														ss=s;
														s=-1;
													}
												}//先倒序找最后一个FCT
												if(ihead==1) {//231222 确保有FCT，才执行以下重置
													ihead=0;
													for(int s=ss;s<len;s++) {//再正序一站一站重置
														iProcessNumber=""+t.getValueAt(s, 2);
														if(iProcessNumber.equals("A0180")) {//从FCT开始
															ihead=1;
														}
														if(ihead==1) {
															iFeedBack=""+t.getValueAt(s, 1);
															if(iFeedBack.equals("1")) {//重置必过站为未过站
																if(!iProcessNumber.equals("A0190")) {//打标签除外
																	fnState=impS.setState((s+1), false);
																}
															}
														}
													}
												}
												
											}
											iState=fnState;
//											mpS.state=fnState;//全检不良从FCT开始230721 //无效，线程外update有概率先做
										}catch(Exception e) {
											;
										}
									}
									// SPI的不良不需要维修管控//密封圈也不需要维修管控//打螺丝也不需要维修管控//除了SPI，其它都要恢复维修管控_20230322
									if((!iiprocedure.equals("A0030"))) {// 烧录软件没改好，无法上传维修
										int iReState=0;// 如果产品编号在自动报废清单中，需要修改为2；//220802品质和生产确认无需此状态
//										String ipart=mysql.selectFirstValue("select partNumber from vOrderList_fast where orderNumber='"
//												+snOrderInfo.masterOrderNumber+"'");
//										JTable iit=sql.select("select part_no from sunlight.product_defective_unrepair_partno where part_no='"
//												+ipart+"'");
//										if((iit!=null)&&(iit.getRowCount()>0)) {
//											iReState=2;// 2是误判，3是报废
//										}	//220802品质和生产确认无需此状态 
										sql.Command("update order_serialNumber set state="+iReState+" where serialNumber='"+iiiiSerialNumber
												+"' and state<>2 and state<>3 ");
										if((iiprocedure.equals("A0180"))) {	//FCT 不良维修增加连续三次PASS管控
											setSNrepeat(iiiiSerialNumber);
										}
									}
//									if((iiprocedure.equals("A0095"))) {// 后道AOI维修管控
//										uploadRepairFlow(iSerialNumber,iResult);//250930 //TODO 后道AOI进维修 
//									}
								}
								sql.Command("update [orderWIP].["+iProcessStateSheet+"] set processState="+iState
										+" where serialNumber='"+iiiiSerialNumber+"'");//2023-07-14 放到线程外 //无法达到外观不良回FCT，改回线程内
								
							} catch (Exception e1) {
								try {
									AKSLogs(-106,e1.getMessage()+"updateProcessState");
								} catch (Exception e) {
									e.printStackTrace();
								}
							}
						}
					}).start();
//					sql.Command("update [orderWIP].["+snOrderInfo.processStateSheet+"] set processState="+mpS.state
//							+" where serialNumber='"+iiiiSerialNumber+"'");//230724  无法达到外观不良回FCT，改回线程内
//					debugStr=iiiiSerialNumber+"debug:"+debugStr+";"+mpS.state;
//					AKSLogs(-230720,debugStr);
				}
				
				
				
				String udateFlag=dateFlag;
				String iprocedure=procedure;
				new Thread(new Runnable() {
					String iiStationID=myStationID;
					String iiLineID=myLineID;
					String iiStationName=myStationName;
					String iiLayer=""+myLayer;
					String iiProcedureNumber=iprocedure;
					String iiFlowListIndex=""+snOrderInfo.flowListIndex;
					String iiOrderNumber=snOrderInfo.orderNumber;
					String idateFlag=udateFlag;
					@Override
					public void run() {
						int result=0;
						try {
							if(iState) {
								result=1;
								if(iRepair) {
									result=2;
									if((iiProcedureNumber.equals("A0030")) && callXRay) {//SPI 复判的要强制AOI前测XRAY  
										try {// callXRay检查是否列表中的位号
											sql.Command("update order_serialNumber set XRayFlag=2 where serialNumber='"+iiiiSerialNumber+"'");
										} catch (Exception e) {
											;
										}
									}
								}
							}
							if(iiProcedureNumber.equals("A0100")) {
								sql.Command("insert history_uploadState (serialNumber,state,stationID,stationName,layer,"
										+ "procedureNumber,flowListIndex,orderNumber) values ('"+iiiiSerialNumber+"',"+result+",'"+iiStationID+"','"
										+iiStationName+"',"+iiLayer+",'"+iiProcedureNumber+"',"+iiFlowListIndex+",'"+iiOrderNumber+"')");
							}
							SQLupdloadHistory(idateFlag,iiiiSerialNumber,result,iiLineID,iiStationID,
									iiStationName,iiLayer,iiProcedureNumber,
									iiFlowListIndex,iiOrderNumber);
						} catch (Exception e1) {
							try {
								AKSLogs(-106,e1.getMessage()+"_uploadState");
							} catch (Exception e) {
								e.printStackTrace();
							}
						}
					}
				}).start();
			}
		}catch(Exception e) {
			throw e;
		}
		
		
	}
	
	protected void setSNrepeat(String iiiiSerialNumber) throws Exception {// 设置重工次数
		sql.Command("update order_serialNumber set repeatCounter=3 where serialNumber='"+iiiiSerialNumber+"'");
	}

	public void SQLupdloadHistory(String dateFlag,String sn,int state, String lineID,String stationID,String stationName,
			String layer,String procedureNumber,String flowListIndex,String orderNumber) throws Exception {
		try {
			sql.Command("insert [SNhistory].[history_uploadState_"+dateFlag+"] (serialNumber,state,lineID,stationID,"
					+ "stationName,layer,procedureNumber,flowListIndex,orderNumber) values ('"
					+sn+"',"+state+","+lineID+",'"+stationID+"','"+stationName+"',"+layer+",'"
					+procedureNumber+"',"+flowListIndex+",'"+orderNumber+"')");
		} catch (Exception e) {
			if(e.getMessage().indexOf("无效")>0) {
				try {
					new c_order(sql).newHistoryDBsheet(dateFlag);
				}catch(Exception ee) {
					;
				}
				sql.Command("insert [SNhistory].[history_uploadState_"+dateFlag+"] (serialNumber,state,lineID,stationID,"
						+ "stationName,layer,procedureNumber,flowListIndex,orderNumber) values ('"
						+sn+"',"+state+","+lineID+",'"+stationID+"','"+stationName+"',"+layer+",'"
						+procedureNumber+"',"+flowListIndex+",'"+orderNumber+"')");
			}else {
				throw e;
			}
		}
	}
	
	public void uploadPanelState(String iSerialNumber,boolean iState,String procedure) throws Exception {
		uploadPanelState(iSerialNumber,iState,false,false,procedure);
	}
	
	public void uploadPanelState(String iSerialNumber,boolean iState,boolean iRepair,boolean callXRay,String procedure) throws Exception {
		if(!isGetStationInfo) {
			throw new Exception("-151");
		}//myProcedureNumber, myLayer已从getStationInfo中获取了,可以直接使用
		if(procedure.equals("-1")) {
			procedure=myProcedureNumber;
		}
		if(!isPanel) {
			uploadState(iSerialNumber,iState,iRepair,callXRay,procedure);
		}else {
			passBy(iState);
			
			/**
			 * 1.获取设备工序，myProcedureNumber, myLayer已从getStationInfo中获取了,可以直接使用
			 * 2.确定本工序在工艺流程中的工步
			 * 3.设置工步结果
			 * 4.update工步结果
			 */
			String SQLstr="select orderNumber,serialNumber,flowListIndex,processStateSheet,"
					+ "pos,initState4sn,createTime from vOrderSerialNumber "
					+ "where panelSN='"+iSerialNumber+"' order by pos";
			JTable t=null;
			if(iSerialNumber.startsWith("NoSN")) {
				if(this.orderActiveRequired) {
					t=sql.select("select '"+this.activeOrderNumber+"','"+iSerialNumber+"',"
							+this.activeOrderInfo[0].flowListIndex+",'"+this.activeOrderInfo[0].processStateSheet
							+"',0,"+this.activeOrderInfo[0].initState4sn+",'"+this.activeOrderInfo[0].createTime+"'");
				}else {
					return;
				}
				
			}else {
				t=sql.select(SQLstr);
				if((t==null)||(t.getRowCount()<1)) {
					String odsql="select panelSN from vOrderSerialNumber where serialNumber='"+iSerialNumber+"'";
					JTable ittt=sql.select(odsql);
					if((ittt!=null)&&(ittt.getRowCount()>0)) {
						iSerialNumber=""+ittt.getValueAt(0, 0);
						SQLstr="select orderNumber,serialNumber,flowListIndex,processStateSheet,"
								+ "pos,initState4sn,createTime from vOrderSerialNumber "
								+ "where panelSN='"+iSerialNumber+"' order by pos";
						t=sql.select(SQLstr);
					}
				}
			}
			
			String gSN=iSerialNumber;
			if((t!=null)&&(t.getRowCount()>0)) {
				JTable gt=t;
				String iprocedure=procedure;
				new Thread(new Runnable() {
					String iiPanelSerialNumber=gSN;
					boolean iiState=iState;
					String iiLineID=myLineID;
					String iiStationID=myStationID;
					String iiStationName=myStationName;
					int iiLayer=myLayer;
					String iiProcedureNumber=iprocedure;
					JTable ttt=gt;
					@Override
					public void run() {
						try {
							c_order co=new c_order(sql);
							Vector<String> sOrders=new Vector<String>();
							Vector<String> masters=new Vector<String>();
							for(int i=0;i<ttt.getRowCount();i++) {
								String gOrderNumber=(String)ttt.getValueAt(i, 0);
								String gSerialNumber=(String)ttt.getValueAt(i, 1);
								int gFlowListIndex=Integer.parseInt((String)ttt.getValueAt(i, 2));
								String gProcessStateSheet=(String)ttt.getValueAt(i, 3);
								String gInitState=(String)ttt.getValueAt(i, 5);
								String gCreateTime=(String)ttt.getValueAt(i, 6);
								String dateFlag=gCreateTime.substring(0, 7);
								dateFlag=dateFlag.replaceAll("-", "");
								dateFlag=dateFlag.replaceAll(":", "");
								dateFlag=dateFlag.replaceAll(" ", "");
								boolean gState=iiState;
								String iiSerialNumber=gSerialNumber;
								int iiFlowListIndex=gFlowListIndex;
								String iiProcessStateSheet=gProcessStateSheet;
								boolean iiiState=gState;
								String iiInitState=gInitState;

								String iiOrderNumber=gOrderNumber;
								try {
									int isPass = 1;
									if(!iiiState) {//登记不良品状态
										isPass=0;
									}else {
										if(iRepair) {
											isPass = 2;
										}
									}
									if(iiPanelSerialNumber.startsWith("NoSN")) {
										iiSerialNumber=iiPanelSerialNumber;
									}else {
										int [] iProcessStepInfo=new c_process(sql).getFlowStep(iiFlowListIndex, iiProcedureNumber, iiLayer,false);
										m_processState mpS=new m_processState();
										mpS.state=0;
										String strSql="select processState from [orderWIP].["+iiProcessStateSheet+"] where serialNumber='"+iiSerialNumber+"'";
										JTable tt=sql.select(strSql);
										if((tt==null)||(tt.getRowCount()<1)) {
											sql.Command("insert [orderWIP].["+iiProcessStateSheet+"] (serialNumber,processState) "
													+ "values ('"+iiSerialNumber+"',"+iiInitState+")");
											tt=sql.select(strSql);
										}
										mpS.state=Long.parseLong((String)tt.getValueAt(0, 0));
										
										mpS.setState(iProcessStepInfo[0], iiiState);
										
										sql.Command("update [orderWIP].["+iiProcessStateSheet+"] set processState="+mpS.state
												+" where serialNumber='"+iiSerialNumber+"'");
										
										if(!iiiState) {//登记不良品状态
											isPass=0;
											if((!iiProcedureNumber.equals("A0030"))) {// SPI的不良不需要维修管控//视觉检测也不需要维修管控
												int iReState=0;// 如果产品编号在自动报废清单中，需要修改为2；
												String ipart=null;
												int soIndex=sOrders.indexOf(iiOrderNumber);
												if(soIndex<0) {
													ipart=co.getMasterPartNumberBySonOrder(iiOrderNumber);
													sOrders.add(iiOrderNumber);
													masters.add(ipart);
												}else {
													ipart=masters.get(soIndex);
												}
//												JTable iit=sql.select("select part_no from sunlight.product_defective_unrepair_partno where part_no='"
//														+ipart+"'");
//												if((iit!=null)&&(iit.getRowCount()>0)) {
//													iReState=2;// 2是误判，3是报废
//												}	////220802品质和生产确认无需此状态
												sql.Command("update order_serialNumber set state="+iReState+" where serialNumber='"+iiSerialNumber
														+"' and state<>2 and state<>3 ");
											}
											if((iiProcedureNumber.equals("A0180"))) {//FCT 不良维修增加连续三次PASS管控
												setSNrepeat(iiSerialNumber);
											}
										}else {
											if(iRepair) {
												isPass = 2;
												if((iiProcedureNumber.equals("A0030")) && callXRay) {//SPI 复判的要强制AOI前测XRAY  
													sql.Command("update order_serialNumber set XRayFlag=2 where serialNumber='"+iiSerialNumber+"'");
												}//callXRay 检查是否列表中的位号
											}
										}
									}
									
									
									SQLupdloadHistory(dateFlag,iiSerialNumber,isPass,iiLineID,iiStationID,
											iiStationName,""+iiLayer,iiProcedureNumber,
											""+iiFlowListIndex,iiOrderNumber);
								} catch (Exception e1) {
									try {
										AKSLogs(-30,"拼板"+iiPanelSerialNumber+"过站失败!"
												+errCodeManagement.getErrText(e1.getMessage()));
									} catch (Exception e) {
										e.printStackTrace();
									}
								}
							}
						} catch (Exception e1) {
							try {
								AKSLogs(-30,"拼板"+iiPanelSerialNumber+"过站失败"
										+errCodeManagement.getErrText(e1.getMessage()));
							} catch (Exception e) {
								e.printStackTrace();
							}
						}
					}
				}).start();
			}else {
				throw new Exception("拼板"+iSerialNumber+"查vOrderSerialNumber子码信息失败");
			}
		}
	}
	
	public void uploadPanelState(String iSerialNumber,m_panelSonResultState [] iState,String procedure) throws Exception {
		if(!isGetStationInfo) {
			throw new Exception("-151");
		}//myProcedureNumber, myLayer已从getStationInfo中获取了,可以直接使用
		if(procedure.equals("-1")) {
			procedure=myProcedureNumber;
		}
		if(!isPanel) {
			throw new Exception("请先激活拼板工单才能按拼板过站!");
		}
		if(iState==null||iState.length<1) {
			throw new Exception("过站结果不能为空");
		}else {
			
			for(int j=0;j<iState.length;j++) {
				passBy(iState[j].isPass);
			}
			
			JTable t=null;
			String SQLstr="";
			if(iSerialNumber.startsWith("NoSN")) {
				if(this.orderActiveRequired) {
					t=sql.select("select '"+this.activeOrderNumber+"',('"+iSerialNumber+"_'+CONVERT(varchar,sequence)) as serialNumber ,"
							+this.activeOrderInfo[0].flowListIndex+",'"+this.activeOrderInfo[0].processStateSheet
							+"',sequence as pos,"+this.activeOrderInfo[0].initState4sn+",'"+this.activeOrderInfo[0].createTime
							+"' from vOrderListPanel where panelOrderNumber='"+activeOrderNumber+"' ");
				}else {
					return;
				}
			}else {
				SQLstr="select orderNumber,serialNumber,flowListIndex,processStateSheet,"
						+ "pos,initState4sn,createTime "
						+ "from vOrderSerialNumber "
						+ "where panelSN='"+iSerialNumber+"' order by pos";
				t=sql.select(SQLstr);
			}
			/**
			 * 1.获取设备工序，myProcedureNumber, myLayer已从getStationInfo中获取了,可以直接使用
			 * 2.确定本工序在工艺流程中的工步
			 * 3.设置工步结果
			 * 4.update工步结果
			 */
			
			if((t==null)||(t.getRowCount()<1)) {
				String odsql="select panelSN from vOrderSerialNumber where serialNumber='"+iSerialNumber+"'";
				JTable ttt=sql.select(odsql);
				if((ttt!=null)&&(ttt.getRowCount()>0)) {
					iSerialNumber=(String)ttt.getValueAt(0, 0);
					SQLstr="select orderNumber,serialNumber,flowListIndex,processStateSheet,"
							+ "pos,initState4sn,createTime "
							+ "from vOrderSerialNumber "
							+ "where panelSN='"+iSerialNumber+"' order by pos";
					t=sql.select(SQLstr);
				}
			}
			if((t!=null)&&(t.getRowCount()>0)) {
				if((!procedure.equals("A0030"))) {// SPI的不良不需要维修管控
					uploadRepairFlow(iSerialNumber,iState);//230809 
				}
				for(int i=0;i<t.getRowCount();i++) {
					String gOrderNumber=(String)t.getValueAt(i, 0);
					String gSerialNumber=(String)t.getValueAt(i, 1);
					int gFlowListIndex=Integer.parseInt((String)t.getValueAt(i, 2));
					String gProcessStateSheet=(String)t.getValueAt(i, 3);
					int gPos=Integer.parseInt((String)t.getValueAt(i, 4));
					String gInitState=(String)t.getValueAt(i, 5);
					String gCreateTime=(String)t.getValueAt(i, 6);
					String dateFlag=gCreateTime.substring(0, 7);
					dateFlag=dateFlag.replaceAll("-", "");
					dateFlag=dateFlag.replaceAll(":", "");
					dateFlag=dateFlag.replaceAll(" ", "");
					m_panelSonResultState [] gState=iState;
					String udateFlag=dateFlag;
					String iprocedure=procedure;
					new Thread(new Runnable() {//子板过站
						String iiiSerialNumber=gSerialNumber;
						int iiFlowListIndex=gFlowListIndex;
						String iiProcessStateSheet=gProcessStateSheet;
						m_panelSonResultState [] iigState=gState;
						int iiPos=gPos;
						String iInitState=gInitState;

						String iiLineID=myLineID;
						String iiStationID=myStationID;
						String iiStationName=myStationName;
						String iiLayer=""+myLayer;
						String iiProcedureNumber=iprocedure;
						String iiOrderNumber=gOrderNumber;
						String idateFlag=udateFlag;
						@Override
						public void run() {
							try {
								boolean flag=false;
								boolean iiiState=false;
								boolean iiiRepair=false;
								boolean icallXRay=false;
								String xRayComps="";
								for(int j=0;j<iigState.length;j++) {
									if(iiPos==iigState[j].pos) {
										flag=true;
										iiiState=iigState[j].isPass;
										iiiRepair=iigState[j].isRepair;
										icallXRay=iigState[j].callXRay;
										xRayComps=iigState[j].xRayComps;
//										System.out.println(""+j+"_"+iiPos+"_"+iiiState+"_"+iiiRepair+",flag="+flag);
									}
								}
								if(flag) {
									int isPass = 1;
									if(!iiiState) {//登记不良品状态
										isPass=0;
									}else {
										if(iiiRepair) {
											isPass = 2;
										}	
									}
									if(!iiiSerialNumber.startsWith("NoSN")) {
										int [] iProcessStepInfo=new c_process(sql).getFlowStep(iiFlowListIndex, iiProcedureNumber, myLayer,false);
										m_processState mpS=new m_processState();
										mpS.state=0;
										String strSql="select processState from [orderWIP].["+iiProcessStateSheet+"] where serialNumber='"+iiiSerialNumber+"'";
										JTable t=sql.select(strSql);
										if((t==null)||(t.getRowCount()<1)) {
											sql.Command("insert [orderWIP].["+iiProcessStateSheet+"] (serialNumber,processState) "
													+ "values ('"+iiiSerialNumber+"',"+iInitState+")");
											t=sql.select(strSql);
										}
										mpS.state=Long.parseLong((String)t.getValueAt(0, 0));
										
										mpS.setState(iProcessStepInfo[0], iiiState);
										
										sql.Command("update [orderWIP].["+iiProcessStateSheet+"] set processState="+mpS.state
												+" where serialNumber='"+iiiSerialNumber+"'");
	//									System.out.println("process_"+iiSerialNumber+"_"+iiPos+"_"+mpS.state);
										
										if(!iiiState) {//登记不良品状态
											isPass=0;
											//SPI的不良不需要维修管控//密封圈也不需要维修管控//打螺丝也不需要维修管控
											if((!iiProcedureNumber.equals("A0030"))) {// SPI的不良不需要维修管控
												int iReState=0;// 如果产品编号在自动报废清单中，需要修改为2；
	//											String sstr="select partNumber from vOrderList_fast where orderNumber in \r\n" + 
	//													"(SELECT masterOrderNumber FROM order_list where orderNumber='"+iiOrderNumber+"')";
	//											String ipart=mysql.selectFirstValue(sstr);
												
	//											JTable iit=sql.select("select part_no from sunlight.product_defective_unrepair_partno where part_no='"
	//													+ipart+"'");
	//											if((iit!=null)&&(iit.getRowCount()>0)) {
	//												iReState=2;// 2是误判，3是报废
	//											}	////220802品质和生产确认无需此状态
												String sstr="update order_serialNumber set state="+iReState+" where serialNumber='"+iiiSerialNumber
														+"' and state<>2 and state<>3 ";
												sql.Command(sstr);
											}
											if((iiProcedureNumber.equals("A0180"))) {//FCT 不良维修增加连续三次PASS管控
												setSNrepeat(iiiSerialNumber);
											}
										}else {
											if(iiiRepair) {
												isPass = 2;
												if((iiProcedureNumber.equals("A0030")) && icallXRay) {//SPI 复判的要强制AOI前测XRAY  
													sql.Command("update order_serialNumber set XRayFlag=2 where serialNumber='"+iiiSerialNumber+"'");
													try {
														sql.Command("insert [SNhistory].[history_resultData_"+idateFlag+"] (serialNumber,[stationID],[equipment],[name],[unit],[min],[max],[value],[result],[lineID]) "
																+ "values ('"+iiiSerialNumber+"','"+iiStationID+"','-','xRayComps','-','-','-','"+xRayComps+"','RPass','"+iiLineID+"') ");
													}catch(Exception ee) {
														new c_order(sql).newHistoryDBsheet(idateFlag);
														sql.Command("insert [SNhistory].[history_resultData_"+idateFlag+"] (serialNumber,[stationID],[equipment],[name],[unit],[min],[max],[value],[result],[lineID]) "
																+ "values ('"+iiiSerialNumber+"','"+iiStationID+"','-','xRayComps','-','-','-','"+xRayComps+"','RPass','"+iiLineID+"') ");
													}
												}//callXRay 检查是否列表中的位号
											}
										}
									}
									SQLupdloadHistory(idateFlag,iiiSerialNumber,isPass,iiLineID,iiStationID,
											iiStationName,""+iiLayer,iiProcedureNumber,
											""+iiFlowListIndex,iiOrderNumber);
								}
							} catch (Exception e1) {
								try {
									AKSLogs(-30,"拼板"+iiiSerialNumber+"过站失败!"+e1.getMessage());
								} catch (Exception e) {
									e.printStackTrace();
								}
							}
						}
					}).start();//子板过站
				}
			}else {
				throw new Exception("拼板"+iSerialNumber+"查vOrderSerialNumber子码信息失败");
			}
		}
	}
	
	
	/**
	 * 	向维修模块上传结果
	 * @param iSerialNumber
	 * @param iState
	 */
	private void uploadRepairFlow(String iSerialNumber, m_panelSonResultState[] iState) {
		new Thread(new Runnable() {
			String iiStationID=myStationID;
			String iiStationName=myStationName;
			String iiLayer=""+myLayer;
			m_order [] iOrderInfo=activeOrderInfo;
			String iiSerialNumber=iSerialNumber;
			m_panelSonResultState[] iiState=iState;
			@Override
			public void run() {
				try {
					if(iiState==null || iiState.length<1) {
						return;
					}
					Vector<m_errormsg> msg=new Vector<m_errormsg>();
					int k=1;
					for(int i=0;i<iiState.length;i++) {
						if(iiState[i]!=null && !iiState[i].isPass) {
							for(int j=0;j<iiState[i].errComps.length;j++ ) {
								if(iiState[i].errComps[j]!=null) {
									m_errormsg ime=new m_errormsg();
									ime.id=""+k++;
									ime.pos=iiState[i].errComps[j].split(",");
									for(int o=0;o<ime.pos.length;o++) {
										ime.pos[o]="("+iiState[i].pos+")"+ime.pos[o];
									}
									ime.error_code=iiState[i].errCode[j];
									msg.add(ime);
								}
							}
						}
					}
					
					if(msg.size()>0) {
						m_uploadRepairFlow_panel result= new m_uploadRepairFlow_panel();
						result.work_station=iiStationName;
						result.side="X";
						if(iiLayer.equals("1")) {
							result.side="T";
						}else if(iiLayer.equals("0")) {
							result.side="B";
						}
						result.sn=iiSerialNumber;
						result.product_name="";
						result.order_no=iOrderInfo[0].panelOrderNumber;
						JTable t=sql.select("select asl.name from [dbo].[assetStation] ass \r\n" + 
								"LEFT JOIN [dbo].[assetLine] asl ON asl.ID=ass.lineID \r\n" + 
								"where ass.ID='"+iiStationID+"'");
						result.line=""+t.getValueAt(0, 0);
						result.creator=iiStationID;
						result.class_name="MES";
						result.errormsg=new m_errormsg[msg.size()];
						for(int i=0;i<msg.size();i++) {
							result.errormsg[i]=msg.get(i);
						}
						result.master_no=iOrderInfo[0].masterNumber;
						result.part_no=iOrderInfo[0].panelNumber;
						
						URLapi aa=new URLapi();
						aa.RESTInvoker("http://10.130.0.231:8092", "","");
						Gson gson=new Gson();
						String ijson=gson.toJson(result);
//						AKSLogs(230810,"uploadRepairFlow_"+ijson);
						String str=aa.postDataToServer("/actionapi/ProductDefective/AddDefectiveaoi", ijson);
						System.out.println(str);
					}
					
				} catch (Exception e1) {
					try {
						AKSLogs(230808,e1.getMessage()+"_uploadRepairFlow");
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		}).start();
	}

	/**
	 * 	过站登记
	 * @param iSerialNumber
	 * @param iState :<BR>
	 * 	true=Pass<BR>
	 * 	false=Fail
	 * @throws Exception
	 */
	public void uploadState_label(String iSerialNumber,boolean iState,String iLabel) throws Exception {
		uploadState(iSerialNumber,iState,"-1");
		new Thread(new Runnable() {
			String iiStationID=myStationID;
			String iiStationName=myStationName;
			String iiLayer=""+myLayer;
			@Override
			public void run() {
				try {// 有过站信息但是没标签信息
					sql.Command("update history_snLabel set state=0 where serialNumber='"+iSerialNumber+"'");
					sql.Command("insert history_snLabel (serialNumber,stationID,stationName,layer,"
							+ "label) values ('"+iSerialNumber+"','"+iiStationID+"','"+iiStationName+"',"+iiLayer+",'"+iLabel+"')");// 添加标签
				} catch (Exception e1) {
					try {
						AKSLogs(-106,e1.getMessage());
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		}).start();
	}
	
	public void uploadPCBresultData(String iPCBSN, List<?> iErrComps) {
		new Thread(new Runnable() {
			String iSerialNumber=iPCBSN;
			String iiStationID=myStationID;
			String iiLineID=myLineID;
			List<?> errComps=iErrComps;
			@Override
			public void run() {
				int i=0;
				try {
					JTable panelT=null;
					if((errComps!=null)&&(errComps.size()>0)) {
						String dateFlag="default";
						// 考虑NoSN的情况

						String SQLstr="select orderNumber,serialNumber,flowListIndex,processStateSheet,"
								+ "pos,initState4sn,createTime from vOrderSerialNumber "
								+ "where serialNumber='"+iSerialNumber+"' order by pos";
						if(iSerialNumber.startsWith("NoSN")) {
							if(orderActiveRequired) {
								panelT=sql.select("select '"+activeOrderNumber+"',('"+iSerialNumber+"_'+CONVERT(varchar,sequence)) as serialNumber ,"
										+activeOrderInfo[0].flowListIndex+",'"+activeOrderInfo[0].processStateSheet
										+"',sequence as pos,"+activeOrderInfo[0].initState4sn+",'"+activeOrderInfo[0].createTime
										+"' from vOrderListPanel where panelOrderNumber='"+activeOrderNumber+"' ");
							}else {
								return;
							}
						}else {
							panelT=sql.select(SQLstr);
						}
						dateFlag=""+panelT.getValueAt(0, 6);
						dateFlag=dateFlag.substring(0, 7);
						dateFlag=dateFlag.replaceAll("-", "");
						dateFlag=dateFlag.replaceAll(":", "");
						dateFlag=dateFlag.replaceAll(" ", "");
						int len=errComps.size();
						String sqlStr="insert [SNhistory].[history_resultData_"+dateFlag+
								"] (serialNumber,[stationID],[equipment],[name],[unit],[min],"
								+ "[max],[value],[result],[lineID]) "
								+ "values ";
						String Gstr=sqlStr;
						int k=0;
						String isn=""+iSerialNumber;
						for(i=0;i<len;i++) {
							String isPass=""+((Element) errComps.get(i)).attribute("Rpass").getValue();
							if(isPass.equals("1")) {
								isPass="0";//MES555中，0=pass
							}else if(isPass.equals("0")){
								isPass="1";//MES555中，1=fail
							}
							String str="('"+isn+"','"+iiStationID+"','-','"
									+((Element) errComps.get(i)).attribute("comps").getValue()
									+"','-','-','-','"
									+((Element) errComps.get(i)).attribute("errCode").getValue()
									+"','"+isPass
									+"','"+iiLineID+"')";
							
							if(k!=0) {
								str=","+str;
							}
							sqlStr=sqlStr+str;
							k=k+1;
							if(k>=900) {
								sqlStr=sqlStr.replace("Ω", "Ω");//前一个特殊字符SQL不识别，需要replace成后面一个，nvarchar可识别
								try {
									sql.Command(sqlStr);
								}catch(Exception ee) {
									new c_order(sql).newHistoryDBsheet(dateFlag);
									sql.Command(sqlStr);
								}finally {
									k=0;
									sqlStr=Gstr;
								}
							}
						}
						if(k>0) {
							sqlStr=sqlStr.replace("Ω", "Ω");//前一个特殊字符SQL不识别，需要replace成后面一个，nvarchar可识别
							try {
								sql.Command(sqlStr);
							}catch(Exception ee) {
								new c_order(sql).newHistoryDBsheet(dateFlag);
								sql.Command(sqlStr);
							}
						}
					}
				} catch (Exception e) {
					try {
						AKSLogs(-106,errCodeManagement.getErrText(e.getMessage())+"_uploadPCBresultData_"+iSerialNumber+"_"+myStationID);
					} catch (Exception e1) {
						;
					}
				}
			}
		}).start();
	}
	

	public void uploadSubPanelResultData(String iPanelSN, String iPos, List<?> iErrComps) {
		new Thread(new Runnable() {
			String iSerialNumber=iPanelSN;
			String iiStationID=myStationID;
			String iiLineID=myLineID;
			List<?> errComps=iErrComps;
			@Override
			public void run() {
				int i=0;
				try {
					JTable panelT=null;
					if((errComps!=null)&&(errComps.size()>0)) {
						String dateFlag="default";
						// 考虑NoSN的情况

						String SQLstr="select orderNumber,serialNumber,flowListIndex,processStateSheet,"
								+ "pos,initState4sn,createTime from vOrderSerialNumber "
								+ "where panelSN='"+iSerialNumber+"' order by pos";
						String gSN=iSerialNumber;
						if(iSerialNumber.startsWith("NoSN")) {
							if(orderActiveRequired) {
								panelT=sql.select("select '"+activeOrderNumber+"',('"+iSerialNumber+"_'+CONVERT(varchar,sequence)) as serialNumber ,"
										+activeOrderInfo[0].flowListIndex+",'"+activeOrderInfo[0].processStateSheet
										+"',sequence as pos,"+activeOrderInfo[0].initState4sn+",'"+activeOrderInfo[0].createTime
										+"' from vOrderListPanel where panelOrderNumber='"+activeOrderNumber+"' ");
							}else {
								return;
							}
						}else {
							panelT=sql.select(SQLstr);
						}
						
						if((panelT==null)||(panelT.getRowCount()<1)) {
							String odsql="select panelSN from vOrderSerialNumber where serialNumber='"+iSerialNumber+"'";
							JTable ttt=sql.select(odsql);
							if((ttt!=null)&&(ttt.getRowCount()>0)) {
								gSN=(String)ttt.getValueAt(0, 0);
								SQLstr="select orderNumber,serialNumber,flowListIndex,processStateSheet,"
										+ "pos,initState4sn,createTime from vOrderSerialNumber "
										+ "where panelSN='"+gSN+"' order by pos";
								panelT=sql.select(SQLstr);
							}else {
								gSN=getSN4Label(iSerialNumber);
								if(gSN==null) {
									throw new Exception("SN不存在_"+iSerialNumber);
								}else {
									odsql="select panelSN from vOrderSerialNumber where serialNumber='"+gSN+"'";
									ttt=sql.select(odsql);
									if((ttt!=null)&&(ttt.getRowCount()>0)) {
										gSN=(String)ttt.getValueAt(0, 0);
										SQLstr="select orderNumber,serialNumber,flowListIndex,processStateSheet,"
												+ "pos,initState4sn,createTime from vOrderSerialNumber "
												+ "where panelSN='"+gSN+"' order by pos";
										panelT=sql.select(SQLstr);
										iSerialNumber=gSN;
									}
								}
							}
						}
						dateFlag=""+panelT.getValueAt(0, 6);
						dateFlag=dateFlag.substring(0, 7);
						dateFlag=dateFlag.replaceAll("-", "");
						dateFlag=dateFlag.replaceAll(":", "");
						dateFlag=dateFlag.replaceAll(" ", "");
						int len=errComps.size();
						String sqlStr="insert [SNhistory].[history_resultData_"+dateFlag+
								"] (serialNumber,[stationID],[equipment],[name],[unit],[min],"
								+ "[max],[value],[result],[lineID]) "
								+ "values ";
						String Gstr=sqlStr;
						int k=0;
						String isn=""+panelT.getValueAt(Integer.parseInt(iPos)-1, 1);
						for(i=0;i<len;i++) {
							String isPass=""+((Element) errComps.get(i)).attribute("Rpass").getValue();
							if(isPass.equals("1")) {
								isPass="0";//MES555中，0=pass
							}else if(isPass.equals("0")){
								isPass="1";//MES555中，1=fail
							}
							String str="('"+isn+"','"+iiStationID+"','-','"
									+((Element) errComps.get(i)).attribute("comps").getValue()
									+"','-','-','-','"
									+((Element) errComps.get(i)).attribute("errCode").getValue()
									+"','"+isPass
									+"','"+iiLineID+"')";
							
							if(k!=0) {
								str=","+str;
							}
							sqlStr=sqlStr+str;
							k=k+1;
							if(k>=900) {
								sqlStr=sqlStr.replace("Ω", "Ω");//前一个特殊字符SQL不识别，需要replace成后面一个，nvarchar可识别
								try {
									sql.Command(sqlStr);
								}catch(Exception ee) {
									new c_order(sql).newHistoryDBsheet(dateFlag);
									sql.Command(sqlStr);
								}finally {
									k=0;
									sqlStr=Gstr;
								}
							}
						}
						if(k>0) {
							sqlStr=sqlStr.replace("Ω", "Ω");//前一个特殊字符SQL不识别，需要replace成后面一个，nvarchar可识别
							try {
								sql.Command(sqlStr);
							}catch(Exception ee) {
								new c_order(sql).newHistoryDBsheet(dateFlag);
								sql.Command(sqlStr);
							}
						}
					}
				} catch (Exception e) {
					try {
						AKSLogs(-106,errCodeManagement.getErrText(e.getMessage())+"_uploadSubPanelResultData_"+iSerialNumber+"_"+myStationID);
					} catch (Exception e1) {
						;
					}
				}
			}
		}).start();
	}
	
	public void uploadData(String iiSerialNumber,m_resultData [] iiData) throws Exception {
		new Thread(new Runnable() {
			String iSerialNumber=iiSerialNumber;
			String iiStationID=myStationID;
			String iiLineID=myLineID;
			m_resultData [] iData=iiData;
			boolean uisPanel=isPanel;
			JTable panelT=null;
			@Override
			public void run() {
				int i=0;
				try {
					if((iData!=null)&&(iData.length>0)) {
						String dateFlag="default";
						// 考虑NoSN的情况
						if(uisPanel) {
							String SQLstr="select orderNumber,serialNumber,flowListIndex,processStateSheet,"
									+ "pos,initState4sn,createTime from vOrderSerialNumber "
									+ "where panelSN='"+iSerialNumber+"' order by pos";
							String gSN=iSerialNumber;
							if(iSerialNumber.startsWith("NoSN")) {
								if(orderActiveRequired) {
									panelT=sql.select("select '"+activeOrderNumber+"',('"+iSerialNumber+"_'+CONVERT(varchar,sequence)) as serialNumber ,"
											+activeOrderInfo[0].flowListIndex+",'"+activeOrderInfo[0].processStateSheet
											+"',sequence as pos,"+activeOrderInfo[0].initState4sn+",'"+activeOrderInfo[0].createTime
											+"' from vOrderListPanel where panelOrderNumber='"+activeOrderNumber+"' ");
								}else {
									return;
								}
							}else {
								panelT=sql.select(SQLstr);
							}
							
							if((panelT==null)||(panelT.getRowCount()<1)) {
								String odsql="select panelSN from vOrderSerialNumber where serialNumber='"+iSerialNumber+"'";
								JTable ttt=sql.select(odsql);
								if((ttt!=null)&&(ttt.getRowCount()>0)) {
									gSN=(String)ttt.getValueAt(0, 0);
									SQLstr="select orderNumber,serialNumber,flowListIndex,processStateSheet,"
											+ "pos,initState4sn,createTime from vOrderSerialNumber "
											+ "where panelSN='"+gSN+"' order by pos";
									panelT=sql.select(SQLstr);
								}else {
									gSN=getSN4Label(iSerialNumber);
									if(gSN==null) {
										throw new Exception("SN不存在_"+iSerialNumber);
									}else {
										odsql="select panelSN from vOrderSerialNumber where serialNumber='"+gSN+"'";
										ttt=sql.select(odsql);
										if((ttt!=null)&&(ttt.getRowCount()>0)) {
											gSN=(String)ttt.getValueAt(0, 0);
											SQLstr="select orderNumber,serialNumber,flowListIndex,processStateSheet,"
													+ "pos,initState4sn,createTime from vOrderSerialNumber "
													+ "where panelSN='"+gSN+"' order by pos";
											panelT=sql.select(SQLstr);
											iSerialNumber=gSN;
										}
									}
								}
							}
							dateFlag=""+panelT.getValueAt(0, 6);
							dateFlag=dateFlag.substring(0, 7);
							dateFlag=dateFlag.replaceAll("-", "");
							dateFlag=dateFlag.replaceAll(":", "");
							dateFlag=dateFlag.replaceAll(" ", "");
						}else {
							if(iSerialNumber.startsWith("NoSN")) {
								dateFlag=activeOrderInfo[0].createTime;
							}else {
								String strSQL="select dateflag from (\r\n" + 
										"select LEFT(CONVERT(VARCHAR(10),createTime,23), 7) as dateflag from [dbo].[order_serialNumber] \r\n" + 
										"where serialNumber ='"+iSerialNumber+"' \r\n" + 
										") A GROUP BY dateflag";
								JTable tDateFlag=sql.select(strSQL);
								if(tDateFlag==null || tDateFlag.getRowCount()<1) {
									String gSN=getSN4Label(iSerialNumber);
									if(gSN==null) {
										throw new Exception("SN不存在_"+iSerialNumber);
									}else {
										strSQL="select dateflag from (\r\n" + 
												"select LEFT(CONVERT(VARCHAR(10),createTime,23), 7) as dateflag from [dbo].[order_serialNumber] \r\n" + 
												"where serialNumber ='"+gSN+"' \r\n" + 
												") A GROUP BY dateflag";
										tDateFlag=sql.select(strSQL);
										if(tDateFlag==null || tDateFlag.getRowCount()<1) {
											throw new Exception("SN不存在_"+iSerialNumber);
										}
										iSerialNumber=gSN;
									}
								}
								dateFlag=""+tDateFlag.getValueAt(0, 0);
							}
							
							dateFlag=dateFlag.replaceAll("-", "");
							dateFlag=dateFlag.replaceAll(":", "");
							dateFlag=dateFlag.replaceAll(" ", "");
						}
						int len=iData.length;
						String sqlStr="insert [SNhistory].[history_resultData_"+dateFlag+
								"] (serialNumber,[stationID],[equipment],[name],[unit],[min],"
								+ "[max],[value],[result],[lineID]) "
								+ "values ";
						String Gstr=sqlStr;
						int k=0;
						for(i=0;i<len;i++) {
							String isn=iSerialNumber;
							if(uisPanel) {
								if(Integer.parseInt(iData[i].pos)>panelT.getRowCount()) {
									continue;
								}
								isn=""+panelT.getValueAt(Integer.parseInt(iData[i].pos)-1, 1);
							}
							String str="('"+isn+"','"+iiStationID+"','"+iData[i].equipment+"','"
									+iData[i].name+"','"+iData[i].unit+"','"+iData[i].min+"','"
									+iData[i].max+"','"+iData[i].value+"','"+iData[i].result+"','"+iiLineID+"')";
							
							if(k!=0) {
								str=","+str;
							}
							sqlStr=sqlStr+str;
							k=k+1;
							if(k>=900) {
								sqlStr=sqlStr.replace("Ω", "Ω");//前一个特殊字符SQL不识别，需要replace成后面一个，nvarchar可识别
								try {
									sql.Command(sqlStr);
								}catch(Exception ee) {
									new c_order(sql).newHistoryDBsheet(dateFlag);
									sql.Command(sqlStr);
								}finally {
									k=0;
									sqlStr=Gstr;
								}
							}
						}
						if(k>0) {
							sqlStr=sqlStr.replace("Ω", "Ω");//前一个特殊字符SQL不识别，需要replace成后面一个，nvarchar可识别
							try {
								sql.Command(sqlStr);
							}catch(Exception ee) {
								new c_order(sql).newHistoryDBsheet(dateFlag);
								sql.Command(sqlStr);
							}
						}
					}
				} catch (Exception e) {
					try {
						AKSLogs(-106,errCodeManagement.getErrText(e.getMessage())+"_updateData_"+iSerialNumber+"_"+iiStationID);
					} catch (Exception e1) {
						;
					}
				}
			}
		}).start();
	}
	
	public String getSN4Label(String iLabel) throws Exception {
		String iSN="";
		try {
			JTable t=sql.select("select serialNumber from history_snLabel where label='"+iLabel+"'");
			if((t!=null)&&(t.getRowCount()>0)) {
				iSN=(String) t.getValueAt(0, 0);
			}else {
				iSN=null;
			}
		} catch (Exception e) {
			throw e;
		}
		return iSN;
	}

	public static String GetTimestamp(){
    	//"2017-12-10 15:52:10";
    	String timestamp=new String();
    	SimpleDateFormat t = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
    	timestamp=""+t.format(new Date());
    	return timestamp;
    }
	
	public static long getDiffMS(String iStartT,String iEndT) {
    	SimpleDateFormat t = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
    	try {
			Date s=t.parse(iStartT);
	    	Date e=t.parse(iEndT);
	    	long diff=e.getTime()-s.getTime();
	    	if(diff<0) {
	    		diff=diff*(-1);
	    	}
	    	return diff;
		} catch (ParseException e1) {
			e1.printStackTrace();
		}
    	return -1;
    }
	
	public void AKSLogs(int iType,String ilogClientNews) {
		SQLtool.AKSLogs(iType, ilogClientNews);
	}

	public void assembling(String iSN, String subPartSN, String subState) throws Exception {
		// subState=isDelete 1=删除，0=装配
		if(subState.equals("0")) {
			try {
				sql.Command("insert assembled (masterSN,partSN) values ('"+iSN+"','"+subPartSN+"')");
			} catch (Exception e) {
				throw new Exception("assembling fail!_"+e.getMessage());
			}
		}else {
			try {
				sql.Command("delete from assembled where masterSN='"+iSN+"' and partSN='"+subPartSN+"'");
			} catch (Exception e) {
				throw new Exception("unbundling fail!_"+e.getMessage());
			}
		}
	}

	public boolean checkWIPfinish(String iSerialNumber) throws Exception {
		if(!isGetStationInfo) {
			throw new Exception("-151");
		}
		if(isPanel) {
			return checkPanelWIPfinish(iSerialNumber);
		}
		String iState,XRayFlag,dateFlag="default";
		int nOrderIndex=-1;
		JTable t=sql.select("select orderIndex,state,XRayFlag,createTime from order_serialNumber where serialNumber='"+iSerialNumber+"'");
		if(t.getRowCount()>0) {
			nOrderIndex=Integer.parseInt((String)t.getValueAt(0, 0));
			iState=(String)t.getValueAt(0, 1);
			XRayFlag=(String)t.getValueAt(0, 2);
			dateFlag=(String)t.getValueAt(0, 3);
			dateFlag=dateFlag.substring(0,7);
			dateFlag=dateFlag.replaceAll("-", "");
			dateFlag=dateFlag.replaceAll(":", "");
			dateFlag=dateFlag.replaceAll(" ", "");
			if(iState.equals("0")||XRayFlag.equals("1")) {
				throw new Exception("-163");	// 品质模块需要判定投入
			}
			if(myProcedureNumber.equals("A0060")) {// AOI检查XRAYflag
				if(XRayFlag.equals("2")) {
					throw new Exception("-173");	// XRay标记没消除，待照XRay
				}
			}
		}else {
			throw new Exception("-152");
		}
		m_order snOrderInfo=new c_order(sql).getOrderInfo_cut(nOrderIndex);
		if(!orderActiveRequired){//无需先激活工单的模式
			sonOrderInfo=snOrderInfo;
			boolean isOld=false;
			if(snOrderInfo.orderNumber.equals(snOrderInfo.masterOrderNumber)&& 
					(!snOrderInfo.orderNumber.startsWith("repair"))) {
				isOld=true;
			}
			myProcessStepInfo=new c_process(sql).getFlowStep(snOrderInfo.flowListIndex, myProcedureNumber, myLayer,isOld);
		}else {//在masterOrder中寻找nOrderNumber是否属于sonOrder,把正确的sonOrder赋值给myOrderInfo，如果不属于则throw new Exception("-153");
			if(sonOrderInfo!=null) {
				if(nOrderIndex!=sonOrderInfo.orderIndex) {
					throw new Exception("-153@"+iSerialNumber+"工单="+snOrderInfo.orderNumber);
				}
			}else{
				boolean checked=false;
				for(int i=0;i<activeOrderInfo.length;i++) {
					if(snOrderInfo.orderIndex==activeOrderInfo[i].orderIndex) {
//						sonOrderInfo=activeOrderInfo[i];//不能认定，有可能故意激活总成工单来做多子板共同进站
						boolean isOld=false;
						checked=true;
						if(snOrderInfo.orderNumber.equals(snOrderInfo.masterOrderNumber)&& 
								(!snOrderInfo.orderNumber.startsWith("repair"))) {
							isOld=true;
						}
						myProcessStepInfo=new c_process(sql).getFlowStep(snOrderInfo.flowListIndex, myProcedureNumber, myLayer,isOld);
						i=activeOrderInfo.length;
					}
				}
				if(checked==false) {
					throw new Exception("-153@"+iSerialNumber+"工单="+snOrderInfo.orderNumber);
				}
			}
		}
		String strSql="select processState from [orderWIP].["+snOrderInfo.processStateSheet+"] where serialNumber='"+iSerialNumber+"'";
		t=sql.select(strSql);
		if((t==null)||(t.getRowCount()<1)) {
			if(nOrderIndex==snOrderInfo.orderIndex) {
				sql.Command("insert [orderWIP].["+snOrderInfo.processStateSheet+"] (serialNumber,processState) "
						+ "values ('"+iSerialNumber+"',"+snOrderInfo.initState4sn+")");
				t=sql.select(strSql);
			}else {//逻辑上不可能发生
				throw new Exception("-153@"+iSerialNumber+"工单="+snOrderInfo.orderNumber);
			}
		}
		m_processState mpS=new m_processState();
		mpS.state=Long.parseLong((String)t.getValueAt(0, 0));
		lastSN=iSerialNumber;
		lastState=mpS.state;
		boolean result=mpS.checkFinishState(myProcessStepInfo[0]);
		if(!result) {// 查查本工序是否FAIL
			JTable tt=null;
			try {
				tt=sql.select("SELECT CreateTime,state FROM [SNhistory].[history_uploadState_"+dateFlag+"] "
					+ "WHERE [procedureNumber] = '"+myProcedureNumber+"' AND [serialNumber] = '"
						+iSerialNumber+"'");
			}catch(Exception e) {
				tt=sql.select("SELECT CreateTime,state FROM [dbo].[history_uploadState] "
						+ "WHERE [procedureNumber] = '"+myProcedureNumber+"' AND [serialNumber] = '"
							+iSerialNumber+"'");
			}
			if(tt!=null&&tt.getRowCount()>0) {
				throw new Exception("NGfinish");
			}
		}
		return result;
	}
	
	public boolean checkPanelWIPfinish(String iSerialNumber) throws Exception {
		if(!isGetStationInfo) {
			throw new Exception("-151");
		}
		if(!isPanel) {
			throw new Exception("请先激活拼板工单才能按拼板检查过站结果!");
		}else {
			String iiSerialNumber=iSerialNumber;
			try {
				/**
				 * 1.获取设备工序，myProcedureNumber, myLayer已从getStationInfo中获取了,可以直接使用
				 * 2.确定本工序在工艺流程中的工步是否已经pass
				 * 3.如果本工步没有pass，查查是否有过履历，有履历即为fail
				 */
				String SQLstr="select orderNumber,serialNumber,flowListIndex,processStateSheet,pos,state,"
						+ "panelOrderNumber,initState4sn,createTime from vOrderSerialNumber "
						+ "where panelSN='"+iiSerialNumber+"' order by pos";
				JTable t=sql.select(SQLstr);
				if((t!=null)&&(t.getRowCount()>0)) {
					checkPanelFinishState=true;
					boolean iResult[]=new boolean[t.getRowCount()];
					String errTest[]=new String[t.getRowCount()];
					Thread [] iT=new Thread[t.getRowCount()];
					for(int i=0;i<t.getRowCount();i++) {
						if(checkPanelFinishState) {
							String gSerialNumber=(String)t.getValueAt(i, 1);
							int gFlowListIndex=Integer.parseInt((String)t.getValueAt(i, 2));
							String gProcessStateSheet=(String)t.getValueAt(i, 3);
							String gPanelOrder=(String)t.getValueAt(i, 6);
							String gCreateTime=(String)t.getValueAt(i, 8);
							String dateFlag=gCreateTime.substring(0, 7);
							dateFlag=dateFlag.replaceAll("-", "");
							dateFlag=dateFlag.replaceAll(":", "");
							dateFlag=dateFlag.replaceAll(" ", "");
							if(orderActiveRequired) {//核对是否符合工单要求
								if(!gPanelOrder.equals(activeOrderNumber)) {
									throw new Exception("-153");
								}
							}
							int iIndex=i;
							String udateFlag=dateFlag;
							iT[i]=new Thread(new Runnable() {//子板过站结果检查
								String iiSerialNumber=gSerialNumber;
								int iiFlowListIndex=gFlowListIndex;
								String iiProcessStateSheet=gProcessStateSheet;
								int iiNdex=iIndex;
								String idateFlag=udateFlag;
								@Override
								public void run() {
									if(checkPanelFinishState) {
										try {
											int [] iProcessStepInfo=new c_process(sql).getFlowStep(iiFlowListIndex, myProcedureNumber, myLayer,false);
											m_processState mpS=new m_processState();
											mpS.state=0;
											String strSql="select processState from [orderWIP].["+iiProcessStateSheet+"] where serialNumber='"+iiSerialNumber+"'";
											JTable t=sql.select(strSql);
											if((t==null)||(t.getRowCount()<1)) {
												iResult[iiNdex]=false;
												JTable tt=null;
												try {
													tt=sql.select("SELECT CreateTime,state FROM [SNhistory].[history_uploadState_"+idateFlag+"] "
															+ "WHERE [procedureNumber] = '"+myProcedureNumber+"' AND [serialNumber] = '"
															+iiSerialNumber+"'");
												}catch(Exception ee) {
													tt=sql.select("SELECT CreateTime,state FROM [dbo].[history_uploadState] "
															+ "WHERE [procedureNumber] = '"+myProcedureNumber+"' AND [serialNumber] = '"
															+iiSerialNumber+"'");
												}
												if(tt!=null&&tt.getRowCount()>0) {
													checkPanelFinishState=false;
												}
												return;
											}
											mpS.state=Long.parseLong((String)t.getValueAt(0, 0));
											iResult[iiNdex]=mpS.checkFinishState(iProcessStepInfo[0]);
											if((checkPanelFinishState)&&(!iResult[iiNdex])) {
												JTable tt=null;
												try {
													tt=sql.select("SELECT CreateTime,state FROM [SNhistory].[history_uploadState_"+idateFlag+"] "
															+ "WHERE [procedureNumber] = '"+myProcedureNumber+"' AND [serialNumber] = '"
															+iiSerialNumber+"'");
												}catch(Exception ee) {
													tt=sql.select("SELECT CreateTime,state FROM [dbo].[history_uploadState] "
															+ "WHERE [procedureNumber] = '"+myProcedureNumber+"' AND [serialNumber] = '"
															+iiSerialNumber+"'");
												}
												if(tt!=null&&tt.getRowCount()>0) {
													checkPanelFinishState=false;
												}
											}
											
										} catch (Exception e1) {
											try {
												errTest[iiNdex]=errCodeManagement.getErrText(e1.getMessage());
												AKSLogs(-32,"拼板中"+iiSerialNumber+"检查过站结果失败!"+e1.getMessage());
											} catch (Exception e) {
												e.printStackTrace();
											}
										}
									}
								}
							});
							iT[i].start();//子板过站
						}
					}
					boolean isFail=false;
					if(checkPanelFinishState) {
						for(int i=0;i<t.getRowCount();i++) {
							if(checkPanelFinishState) {
								iT[i].join();
								if(!iResult[i]) {
									isFail=true;
								}
							}else {
								throw new Exception("NGfinish");
							}
						}
						return (!isFail);
					}else {
						throw new Exception("NGfinish");
					}
				}else {
					throw new Exception("拼板"+iiSerialNumber+"查vOrderSerialNumber子码信息失败");
				}
				
			} catch (Exception e1) {
				try {
					AKSLogs(-32,"拼板"+iiSerialNumber+"过站结果失败"+e1.getMessage());
				} catch (Exception e) {
					e.printStackTrace();
				}
				return false;
			}
		}
	}

	
	public void setSQL(SQLtool iisql) throws Exception {
		try {
			sql.close();
		}catch(Exception e) {}
		sql=iisql;
//		try {
//			iPC.close();
//		}catch(Exception e) {}
//		iPC=new productionCounter(iisql);
//		iPC.setStationID(myStationID);
//		iPC.start();
	}
	
	public void close() throws Exception {
//		iPC.close();
//		sql.close();
	}
}
